summaryrefslogtreecommitdiffstats
path: root/drivers/net/realtek-dsa/tagger.c
blob: 3a41f3b3c1b45d8dfd550a8fee7d88c0e4244581 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// SPDX-License-Identifier: GPL-2.0-or-later

#include "realtek.h"

int realtek_dsa_init_tagger(struct realtek_priv *priv)
{
	const struct dsa_device_ops *tagger_ops = NULL;
	struct dsa_switch_ops *ops;

	/* TODO: Tagging can be configured per port in Linux. barebox DSA core
	 * will need some refactoring to do that. For now we just use the
	 * Linux default and leave ->change_tag_protocol unused and
	 * dsa-tag-protocol OF properties unheeded.
	 */
	switch (priv->ops->get_tag_protocol(priv)) {
	case DSA_TAG_PROTO_RTL4_A:
		if (IS_ENABLED(CONFIG_NET_DSA_TAG_RTL4_A))
			tagger_ops = &rtl4a_netdev_ops;
		break;
	case DSA_TAG_PROTO_RTL8_4:
		if (IS_ENABLED(CONFIG_NET_DSA_TAG_RTL8_4))
			tagger_ops = &rtl8_4_netdev_ops;
		break;
	case DSA_TAG_PROTO_RTL8_4T:
		if (IS_ENABLED(CONFIG_NET_DSA_TAG_RTL8_4))
			tagger_ops = &rtl8_4t_netdev_ops;
		break;
	default:
		break;
	}

	if (!tagger_ops)
		return -EINVAL;

	ops = memdup(priv->ds->ops, sizeof(*priv->ds->ops));
	ops->xmit = tagger_ops->xmit;
	ops->rcv = tagger_ops->rcv;
	priv->ds->ops = ops;
	priv->ds->needed_headroom = tagger_ops->needed_headroom;
	priv->ds->needed_rx_tailroom = tagger_ops->needed_tailroom;
	priv->ds->needed_tx_tailroom = tagger_ops->needed_tailroom;

	return 0;
}