net/dsa/tag_ksz.c

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

File Facts

System
Linux kernel
Corpus path
net/dsa/tag_ksz.c
Extension
.c
Size
13155 bytes
Lines
466
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

struct ksz_tagger_private {
	struct ksz_tagger_data data; /* Must be first */
	unsigned long state;
	struct kthread_worker *xmit_worker;
};

static struct ksz_tagger_private *
ksz_tagger_private(struct dsa_switch *ds)
{
	return ds->tagger_data;
}

static void ksz_hwtstamp_set_state(struct dsa_switch *ds, bool on)
{
	struct ksz_tagger_private *priv = ksz_tagger_private(ds);

	if (on)
		set_bit(KSZ_HWTS_EN, &priv->state);
	else
		clear_bit(KSZ_HWTS_EN, &priv->state);
}

static void ksz_disconnect(struct dsa_switch *ds)
{
	struct ksz_tagger_private *priv = ds->tagger_data;

	kthread_destroy_worker(priv->xmit_worker);
	kfree(priv);
	ds->tagger_data = NULL;
}

static int ksz_connect(struct dsa_switch *ds)
{
	struct ksz_tagger_data *tagger_data;
	struct kthread_worker *xmit_worker;
	struct ksz_tagger_private *priv;
	int ret;

	priv = kzalloc_obj(*priv);
	if (!priv)
		return -ENOMEM;

	xmit_worker = kthread_run_worker(0, "dsa%d:%d_xmit",
					    ds->dst->index, ds->index);
	if (IS_ERR(xmit_worker)) {
		ret = PTR_ERR(xmit_worker);
		kfree(priv);
		return ret;
	}

	priv->xmit_worker = xmit_worker;
	/* Export functions for switch driver use */
	tagger_data = &priv->data;
	tagger_data->hwtstamp_set_state = ksz_hwtstamp_set_state;
	ds->tagger_data = priv;

	return 0;
}

static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
				      struct net_device *dev,
				      unsigned int port, unsigned int len)
{
	skb->dev = dsa_conduit_find_user(dev, 0, port);
	if (!skb->dev)
		return NULL;

	if (pskb_trim_rcsum(skb, skb->len - len))
		return NULL;

	dsa_default_offload_fwd_mark(skb);

	return skb;
}

/*
 * For Ingress (Host -> KSZ8795), 1 byte is added before FCS.
 * ---------------------------------------------------------------------------
 * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag(1byte)|FCS(4bytes)
 * ---------------------------------------------------------------------------
 * tag : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
 *
 * For Egress (KSZ8795 -> Host), 1 byte is added before FCS.
 * ---------------------------------------------------------------------------
 * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
 * ---------------------------------------------------------------------------
 * tag0 : zero-based value represents port
 *	  (eg, 0x0=port1, 0x2=port3, 0x3=port4)
 */

Annotation

Implementation Notes