File Index
Files and directories
Sign in
FILE

tag_gswip.c

File preview with syntax highlighting.

linux-6.19.14/net/dsa/tag_gswip.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Intel / Lantiq GSWIP V2.0 PMAC tag support
  4 *
  5 * Copyright (C) 2017 - 2018 Hauke Mehrtens <hauke@hauke-m.de>
  6 */
  7
  8#include <linux/bitops.h>
  9#include <linux/etherdevice.h>
 10#include <linux/skbuff.h>
 11#include <net/dsa.h>
 12
 13#include "tag.h"
 14
 15#define GSWIP_NAME			"gswip"
 16
 17#define GSWIP_TX_HEADER_LEN		4
 18
 19/* special tag in TX path header */
 20/* Byte 0 */
 21#define GSWIP_TX_SLPID_SHIFT		0	/* source port ID */
 22#define  GSWIP_TX_SLPID_CPU		2
 23#define  GSWIP_TX_SLPID_APP1		3
 24#define  GSWIP_TX_SLPID_APP2		4
 25#define  GSWIP_TX_SLPID_APP3		5
 26#define  GSWIP_TX_SLPID_APP4		6
 27#define  GSWIP_TX_SLPID_APP5		7
 28
 29/* Byte 1 */
 30#define GSWIP_TX_CRCGEN_DIS		BIT(7)
 31#define GSWIP_TX_DPID_SHIFT		0	/* destination group ID */
 32#define  GSWIP_TX_DPID_ELAN		0
 33#define  GSWIP_TX_DPID_EWAN		1
 34#define  GSWIP_TX_DPID_CPU		2
 35#define  GSWIP_TX_DPID_APP1		3
 36#define  GSWIP_TX_DPID_APP2		4
 37#define  GSWIP_TX_DPID_APP3		5
 38#define  GSWIP_TX_DPID_APP4		6
 39#define  GSWIP_TX_DPID_APP5		7
 40
 41/* Byte 2 */
 42#define GSWIP_TX_PORT_MAP_EN		BIT(7)
 43#define GSWIP_TX_PORT_MAP_SEL		BIT(6)
 44#define GSWIP_TX_LRN_DIS		BIT(5)
 45#define GSWIP_TX_CLASS_EN		BIT(4)
 46#define GSWIP_TX_CLASS_SHIFT		0
 47#define GSWIP_TX_CLASS_MASK		GENMASK(3, 0)
 48
 49/* Byte 3 */
 50#define GSWIP_TX_DPID_EN		BIT(0)
 51#define GSWIP_TX_PORT_MAP		GENMASK(6, 1)
 52
 53#define GSWIP_RX_HEADER_LEN	8
 54
 55/* special tag in RX path header */
 56/* Byte 7 */
 57#define GSWIP_RX_SPPID_SHIFT		4
 58#define GSWIP_RX_SPPID_MASK		GENMASK(6, 4)
 59
 60static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
 61				      struct net_device *dev)
 62{
 63	u8 *gswip_tag;
 64
 65	skb_push(skb, GSWIP_TX_HEADER_LEN);
 66
 67	gswip_tag = skb->data;
 68	gswip_tag[0] = GSWIP_TX_SLPID_CPU;
 69	gswip_tag[1] = GSWIP_TX_DPID_ELAN;
 70	gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
 71	gswip_tag[3] = FIELD_PREP(GSWIP_TX_PORT_MAP, dsa_xmit_port_mask(skb, dev));
 72	gswip_tag[3] |= GSWIP_TX_DPID_EN;
 73
 74	return skb;
 75}
 76
 77static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
 78				     struct net_device *dev)
 79{
 80	int port;
 81	u8 *gswip_tag;
 82
 83	if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
 84		return NULL;
 85
 86	gswip_tag = skb->data - ETH_HLEN;
 87
 88	/* Get source port information */
 89	port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
 90	skb->dev = dsa_conduit_find_user(dev, 0, port);
 91	if (!skb->dev)
 92		return NULL;
 93
 94	/* remove GSWIP tag */
 95	skb_pull_rcsum(skb, GSWIP_RX_HEADER_LEN);
 96
 97	return skb;
 98}
 99
100static const struct dsa_device_ops gswip_netdev_ops = {
101	.name = GSWIP_NAME,
102	.proto	= DSA_TAG_PROTO_GSWIP,
103	.xmit = gswip_tag_xmit,
104	.rcv = gswip_tag_rcv,
105	.needed_headroom = GSWIP_RX_HEADER_LEN,
106};
107
108MODULE_DESCRIPTION("DSA tag driver for Lantiq / Intel GSWIP switches");
109MODULE_LICENSE("GPL");
110MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP, GSWIP_NAME);
111
112module_dsa_tag_driver(gswip_netdev_ops);
~/ Read-only file preview.