Linux Audio

Check our new training course

Loading...
v6.13.7
  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_SHIFT		1
 52#define GSWIP_TX_PORT_MAP_MASK		GENMASK(6, 1)
 53
 54#define GSWIP_RX_HEADER_LEN	8
 55
 56/* special tag in RX path header */
 57/* Byte 7 */
 58#define GSWIP_RX_SPPID_SHIFT		4
 59#define GSWIP_RX_SPPID_MASK		GENMASK(6, 4)
 60
 61static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
 62				      struct net_device *dev)
 63{
 64	struct dsa_port *dp = dsa_user_to_port(dev);
 65	u8 *gswip_tag;
 66
 67	skb_push(skb, GSWIP_TX_HEADER_LEN);
 68
 69	gswip_tag = skb->data;
 70	gswip_tag[0] = GSWIP_TX_SLPID_CPU;
 71	gswip_tag[1] = GSWIP_TX_DPID_ELAN;
 72	gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
 73	gswip_tag[3] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
 74	gswip_tag[3] |= GSWIP_TX_DPID_EN;
 75
 76	return skb;
 77}
 78
 79static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
 80				     struct net_device *dev)
 
 81{
 82	int port;
 83	u8 *gswip_tag;
 84
 85	if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
 86		return NULL;
 87
 88	gswip_tag = skb->data - ETH_HLEN;
 89
 90	/* Get source port information */
 91	port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
 92	skb->dev = dsa_conduit_find_user(dev, 0, port);
 93	if (!skb->dev)
 94		return NULL;
 95
 96	/* remove GSWIP tag */
 97	skb_pull_rcsum(skb, GSWIP_RX_HEADER_LEN);
 98
 99	return skb;
100}
101
102static const struct dsa_device_ops gswip_netdev_ops = {
103	.name = GSWIP_NAME,
104	.proto	= DSA_TAG_PROTO_GSWIP,
105	.xmit = gswip_tag_xmit,
106	.rcv = gswip_tag_rcv,
107	.needed_headroom = GSWIP_RX_HEADER_LEN,
108};
109
110MODULE_DESCRIPTION("DSA tag driver for Lantiq / Intel GSWIP switches");
111MODULE_LICENSE("GPL");
112MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP, GSWIP_NAME);
113
114module_dsa_tag_driver(gswip_netdev_ops);
v5.14.15
  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 "dsa_priv.h"
 
 
 14
 15#define GSWIP_TX_HEADER_LEN		4
 16
 17/* special tag in TX path header */
 18/* Byte 0 */
 19#define GSWIP_TX_SLPID_SHIFT		0	/* source port ID */
 20#define  GSWIP_TX_SLPID_CPU		2
 21#define  GSWIP_TX_SLPID_APP1		3
 22#define  GSWIP_TX_SLPID_APP2		4
 23#define  GSWIP_TX_SLPID_APP3		5
 24#define  GSWIP_TX_SLPID_APP4		6
 25#define  GSWIP_TX_SLPID_APP5		7
 26
 27/* Byte 1 */
 28#define GSWIP_TX_CRCGEN_DIS		BIT(7)
 29#define GSWIP_TX_DPID_SHIFT		0	/* destination group ID */
 30#define  GSWIP_TX_DPID_ELAN		0
 31#define  GSWIP_TX_DPID_EWAN		1
 32#define  GSWIP_TX_DPID_CPU		2
 33#define  GSWIP_TX_DPID_APP1		3
 34#define  GSWIP_TX_DPID_APP2		4
 35#define  GSWIP_TX_DPID_APP3		5
 36#define  GSWIP_TX_DPID_APP4		6
 37#define  GSWIP_TX_DPID_APP5		7
 38
 39/* Byte 2 */
 40#define GSWIP_TX_PORT_MAP_EN		BIT(7)
 41#define GSWIP_TX_PORT_MAP_SEL		BIT(6)
 42#define GSWIP_TX_LRN_DIS		BIT(5)
 43#define GSWIP_TX_CLASS_EN		BIT(4)
 44#define GSWIP_TX_CLASS_SHIFT		0
 45#define GSWIP_TX_CLASS_MASK		GENMASK(3, 0)
 46
 47/* Byte 3 */
 48#define GSWIP_TX_DPID_EN		BIT(0)
 49#define GSWIP_TX_PORT_MAP_SHIFT		1
 50#define GSWIP_TX_PORT_MAP_MASK		GENMASK(6, 1)
 51
 52#define GSWIP_RX_HEADER_LEN	8
 53
 54/* special tag in RX path header */
 55/* Byte 7 */
 56#define GSWIP_RX_SPPID_SHIFT		4
 57#define GSWIP_RX_SPPID_MASK		GENMASK(6, 4)
 58
 59static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
 60				      struct net_device *dev)
 61{
 62	struct dsa_port *dp = dsa_slave_to_port(dev);
 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] = BIT(dp->index + GSWIP_TX_PORT_MAP_SHIFT) & GSWIP_TX_PORT_MAP_MASK;
 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				     struct packet_type *pt)
 80{
 81	int port;
 82	u8 *gswip_tag;
 83
 84	if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
 85		return NULL;
 86
 87	gswip_tag = skb->data - ETH_HLEN;
 88
 89	/* Get source port information */
 90	port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
 91	skb->dev = dsa_master_find_slave(dev, 0, port);
 92	if (!skb->dev)
 93		return NULL;
 94
 95	/* remove GSWIP tag */
 96	skb_pull_rcsum(skb, GSWIP_RX_HEADER_LEN);
 97
 98	return skb;
 99}
100
101static const struct dsa_device_ops gswip_netdev_ops = {
102	.name = "gswip",
103	.proto	= DSA_TAG_PROTO_GSWIP,
104	.xmit = gswip_tag_xmit,
105	.rcv = gswip_tag_rcv,
106	.needed_headroom = GSWIP_RX_HEADER_LEN,
107};
108
 
109MODULE_LICENSE("GPL");
110MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP);
111
112module_dsa_tag_driver(gswip_netdev_ops);