net/dsa/tag_gswip.c

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

File Facts

System
Linux kernel
Corpus path
net/dsa/tag_gswip.c
Extension
.c
Size
2802 bytes
Lines
113
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Intel / Lantiq GSWIP V2.0 PMAC tag support
 *
 * Copyright (C) 2017 - 2018 Hauke Mehrtens <hauke@hauke-m.de>
 */

#include <linux/bitops.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <net/dsa.h>

#include "tag.h"

#define GSWIP_NAME			"gswip"

#define GSWIP_TX_HEADER_LEN		4

/* special tag in TX path header */
/* Byte 0 */
#define GSWIP_TX_SLPID_SHIFT		0	/* source port ID */
#define  GSWIP_TX_SLPID_CPU		2
#define  GSWIP_TX_SLPID_APP1		3
#define  GSWIP_TX_SLPID_APP2		4
#define  GSWIP_TX_SLPID_APP3		5
#define  GSWIP_TX_SLPID_APP4		6
#define  GSWIP_TX_SLPID_APP5		7

/* Byte 1 */
#define GSWIP_TX_CRCGEN_DIS		BIT(7)
#define GSWIP_TX_DPID_SHIFT		0	/* destination group ID */
#define  GSWIP_TX_DPID_ELAN		0
#define  GSWIP_TX_DPID_EWAN		1
#define  GSWIP_TX_DPID_CPU		2
#define  GSWIP_TX_DPID_APP1		3
#define  GSWIP_TX_DPID_APP2		4
#define  GSWIP_TX_DPID_APP3		5
#define  GSWIP_TX_DPID_APP4		6
#define  GSWIP_TX_DPID_APP5		7

/* Byte 2 */
#define GSWIP_TX_PORT_MAP_EN		BIT(7)
#define GSWIP_TX_PORT_MAP_SEL		BIT(6)
#define GSWIP_TX_LRN_DIS		BIT(5)
#define GSWIP_TX_CLASS_EN		BIT(4)
#define GSWIP_TX_CLASS_SHIFT		0
#define GSWIP_TX_CLASS_MASK		GENMASK(3, 0)

/* Byte 3 */
#define GSWIP_TX_DPID_EN		BIT(0)
#define GSWIP_TX_PORT_MAP		GENMASK(6, 1)

#define GSWIP_RX_HEADER_LEN	8

/* special tag in RX path header */
/* Byte 7 */
#define GSWIP_RX_SPPID_SHIFT		4
#define GSWIP_RX_SPPID_MASK		GENMASK(6, 4)

static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb,
				      struct net_device *dev)
{
	u8 *gswip_tag;

	skb_push(skb, GSWIP_TX_HEADER_LEN);

	gswip_tag = skb->data;
	gswip_tag[0] = GSWIP_TX_SLPID_CPU;
	gswip_tag[1] = GSWIP_TX_DPID_ELAN;
	gswip_tag[2] = GSWIP_TX_PORT_MAP_EN | GSWIP_TX_PORT_MAP_SEL;
	gswip_tag[3] = FIELD_PREP(GSWIP_TX_PORT_MAP, dsa_xmit_port_mask(skb, dev));
	gswip_tag[3] |= GSWIP_TX_DPID_EN;

	return skb;
}

static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
				     struct net_device *dev)
{
	int port;
	u8 *gswip_tag;

	if (unlikely(!pskb_may_pull(skb, GSWIP_RX_HEADER_LEN)))
		return NULL;

	gswip_tag = skb->data - ETH_HLEN;

	/* Get source port information */
	port = (gswip_tag[7] & GSWIP_RX_SPPID_MASK) >> GSWIP_RX_SPPID_SHIFT;
	skb->dev = dsa_conduit_find_user(dev, 0, port);

Annotation

Implementation Notes