linux/net/dsa/tag_sja1105.c

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019, Vladimir Oltean <[email protected]>
 */
#include <linux/if_vlan.h>
#include <linux/dsa/sja1105.h>
#include <linux/dsa/8021q.h>
#include <linux/packing.h>

#include "tag.h"
#include "tag_8021q.h"

#define SJA1105_NAME
#define SJA1110_NAME

/* Is this a TX or an RX header? */
#define SJA1110_HEADER_HOST_TO_SWITCH

/* RX header */
#define SJA1110_RX_HEADER_IS_METADATA
#define SJA1110_RX_HEADER_HOST_ONLY
#define SJA1110_RX_HEADER_HAS_TRAILER

/* Trap-to-host format (no trailer present) */
#define SJA1110_RX_HEADER_SRC_PORT(x)
#define SJA1110_RX_HEADER_SWITCH_ID(x)

/* Timestamp format (trailer present) */
#define SJA1110_RX_HEADER_TRAILER_POS(x)

#define SJA1110_RX_TRAILER_SWITCH_ID(x)
#define SJA1110_RX_TRAILER_SRC_PORT(x)

/* Meta frame format (for 2-step TX timestamps) */
#define SJA1110_RX_HEADER_N_TS(x)

/* TX header */
#define SJA1110_TX_HEADER_UPDATE_TC
#define SJA1110_TX_HEADER_TAKE_TS
#define SJA1110_TX_HEADER_TAKE_TS_CASC
#define SJA1110_TX_HEADER_HAS_TRAILER

/* Only valid if SJA1110_TX_HEADER_HAS_TRAILER is false */
#define SJA1110_TX_HEADER_PRIO(x)
#define SJA1110_TX_HEADER_TSTAMP_ID(x)

/* Only valid if SJA1110_TX_HEADER_HAS_TRAILER is true */
#define SJA1110_TX_HEADER_TRAILER_POS(x)

#define SJA1110_TX_TRAILER_TSTAMP_ID(x)
#define SJA1110_TX_TRAILER_PRIO(x)
#define SJA1110_TX_TRAILER_SWITCHID(x)
#define SJA1110_TX_TRAILER_DESTPORTS(x)

#define SJA1110_META_TSTAMP_SIZE

#define SJA1110_HEADER_LEN
#define SJA1110_RX_TRAILER_LEN
#define SJA1110_TX_TRAILER_LEN
#define SJA1110_MAX_PADDING_LEN

struct sja1105_tagger_private {};

static struct sja1105_tagger_private *
sja1105_tagger_private(struct dsa_switch *ds)
{}

/* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */
static bool sja1105_is_link_local(const struct sk_buff *skb)
{}

struct sja1105_meta {};

static void sja1105_meta_unpack(const struct sk_buff *skb,
				struct sja1105_meta *meta)
{}

static bool sja1105_is_meta_frame(const struct sk_buff *skb)
{}

/* Calls sja1105_port_deferred_xmit in sja1105_main.c */
static struct sk_buff *sja1105_defer_xmit(struct dsa_port *dp,
					  struct sk_buff *skb)
{}

/* Send VLAN tags with a TPID that blends in with whatever VLAN protocol a
 * bridge spanning ports of this switch might have.
 */
static u16 sja1105_xmit_tpid(struct dsa_port *dp)
{}

static struct sk_buff *sja1105_imprecise_xmit(struct sk_buff *skb,
					      struct net_device *netdev)
{}

/* Transform untagged control packets into pvid-tagged control packets so that
 * all packets sent by this tagger are VLAN-tagged and we can configure the
 * switch to drop untagged packets coming from the DSA conduit.
 */
static struct sk_buff *sja1105_pvid_tag_control_pkt(struct dsa_port *dp,
						    struct sk_buff *skb, u8 pcp)
{}

static struct sk_buff *sja1105_xmit(struct sk_buff *skb,
				    struct net_device *netdev)
{}

static struct sk_buff *sja1110_xmit(struct sk_buff *skb,
				    struct net_device *netdev)
{}

static void sja1105_transfer_meta(struct sk_buff *skb,
				  const struct sja1105_meta *meta)
{}

/* This is a simple state machine which follows the hardware mechanism of
 * generating RX timestamps:
 *
 * After each timestampable skb (all traffic for which send_meta1 and
 * send_meta0 is true, aka all MAC-filtered link-local traffic) a meta frame
 * containing a partial timestamp is immediately generated by the switch and
 * sent as a follow-up to the link-local frame on the CPU port.
 *
 * The meta frames have no unique identifier (such as sequence number) by which
 * one may pair them to the correct timestampable frame.
 * Instead, the switch has internal logic that ensures no frames are sent on
 * the CPU port between a link-local timestampable frame and its corresponding
 * meta follow-up. It also ensures strict ordering between ports (lower ports
 * have higher priority towards the CPU port). For this reason, a per-port
 * data structure is not needed/desirable.
 *
 * This function pairs the link-local frame with its partial timestamp from the
 * meta follow-up frame. The full timestamp will be reconstructed later in a
 * work queue.
 */
static struct sk_buff
*sja1105_rcv_meta_state_machine(struct sk_buff *skb,
				struct sja1105_meta *meta,
				bool is_link_local,
				bool is_meta)
{}

static bool sja1105_skb_has_tag_8021q(const struct sk_buff *skb)
{}

static bool sja1110_skb_has_inband_control_extension(const struct sk_buff *skb)
{}

static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
				   struct net_device *netdev)
{}

static struct sk_buff *sja1110_rcv_meta(struct sk_buff *skb, u16 rx_header)
{}

static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
							    int *source_port,
							    int *switch_id,
							    bool *host_only)
{}

static struct sk_buff *sja1110_rcv(struct sk_buff *skb,
				   struct net_device *netdev)
{}

static void sja1105_flow_dissect(const struct sk_buff *skb, __be16 *proto,
				 int *offset)
{}

static void sja1110_flow_dissect(const struct sk_buff *skb, __be16 *proto,
				 int *offset)
{}

static void sja1105_disconnect(struct dsa_switch *ds)
{}

static int sja1105_connect(struct dsa_switch *ds)
{}

static const struct dsa_device_ops sja1105_netdev_ops =;

DSA_TAG_DRIVER(sja1105_netdev_ops);
MODULE_ALIAS_DSA_TAG_DRIVER();

static const struct dsa_device_ops sja1110_netdev_ops =;

DSA_TAG_DRIVER(sja1110_netdev_ops);
MODULE_ALIAS_DSA_TAG_DRIVER();

static struct dsa_tag_driver *sja1105_tag_driver_array[] =;

module_dsa_tag_drivers(sja1105_tag_driver_array);

MODULE_DESCRIPTION();
MODULE_LICENSE();