Commit c49379dc authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-dsa-vsc73xx-implement-vlan-operations'

Pawel Dembicki says:

====================
net: dsa: vsc73xx: Implement VLAN operations

This patch series is a result of splitting a larger patch series [0],
where some parts was merged before.

The first patch implements port state configuration, which is required
for bridge functionality. STP frames are not forwarded at this moment.
BPDU frames are only forwarded from/to the PI/SI interface.
For more information, see chapter 2.7.1 (CPU Forwarding) in the
datasheet.

Patches 2, 7-9 and 11 provide a basic implementation of tag_8021q
functionality with QinQ support, without VLAN filtering in
the bridge and simple VLAN awareness in VLAN filtering mode.

Patches 3-6 came from Vladimir Oltean. They prepare for making
tag8021q more common. VSC73XX uses very similar tag recognition,
and some code from tag_sja1105 could be moved to tag_8021q for
common use.

Patch 10 is preparation for use tag_8021q bridge functions as generic
implementation of the 'ds->ops->port_bridge_*()'.

Patch 12 is required to avoid problem with learning on standalone ports.

[0] https://patchwork.kernel.org/project/netdevbpf/list/?series=841034&state=%2A&archive=both
====================

Link: https://patch.msgid.link/20240713211620.1125910-1-paweldembicki@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a8ea8d53 259a7061
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ config NET_DSA_SMSC_LAN9303_MDIO

config NET_DSA_VITESSE_VSC73XX
	tristate
	select NET_DSA_TAG_NONE
	select NET_DSA_TAG_VSC73XX_8021Q
	select FIXED_PHY
	select VITESSE_PHY
	select GPIOLIB
+3 −5
Original line number Diff line number Diff line
@@ -2133,14 +2133,13 @@ static int sja1105_bridge_join(struct dsa_switch *ds, int port,
	if (rc)
		return rc;

	rc = dsa_tag_8021q_bridge_join(ds, port, bridge);
	rc = dsa_tag_8021q_bridge_join(ds, port, bridge, tx_fwd_offload,
				       extack);
	if (rc) {
		sja1105_bridge_member(ds, port, bridge, false);
		return rc;
	}

	*tx_fwd_offload = true;

	return 0;
}

@@ -3167,8 +3166,7 @@ static int sja1105_setup(struct dsa_switch *ds)
	ds->vlan_filtering_is_global = true;
	ds->untag_bridge_pvid = true;
	ds->fdb_isolation = true;
	/* tag_8021q has 3 bits for the VBID, and the value 0 is reserved */
	ds->max_num_bridges = 7;
	ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES;

	/* Advertise the 8 egress queues */
	ds->num_tx_queues = SJA1105_NUM_TC;
+718 −17

File changed.

Preview size limit exceeded, changes collapsed.

+37 −0
Original line number Diff line number Diff line
@@ -14,6 +14,22 @@
 */
#define VSC73XX_MAX_NUM_PORTS	8

/**
 * struct vsc73xx_portinfo - port data structure: contains storage data
 * @pvid_vlan_filtering: pvid vlan number used in vlan filtering mode
 * @pvid_tag_8021q: pvid vlan number used in tag_8021q mode
 * @pvid_vlan_filtering_configured: informs if port has configured pvid in vlan
 *	filtering mode
 * @pvid_tag_8021q_configured: imforms if port have configured pvid in tag_8021q
 *	mode
 */
struct vsc73xx_portinfo {
	u16		pvid_vlan_filtering;
	u16		pvid_tag_8021q;
	bool		pvid_vlan_filtering_configured;
	bool		pvid_tag_8021q_configured;
};

/**
 * struct vsc73xx - VSC73xx state container: main data structure
 * @dev: The device pointer
@@ -25,6 +41,10 @@
 * @addr: MAC address used in flow control frames
 * @ops: Structure with hardware-dependent operations
 * @priv: Pointer to the configuration interface structure
 * @portinfo: Storage table portinfo structructures
 * @vlans: List of configured vlans. Contains port mask and untagged status of
 *	every vlan configured in port vlan operation. It doesn't cover tag_8021q
 *	vlans.
 */
struct vsc73xx {
	struct device			*dev;
@@ -35,6 +55,8 @@ struct vsc73xx {
	u8				addr[ETH_ALEN];
	const struct vsc73xx_ops	*ops;
	void				*priv;
	struct vsc73xx_portinfo		portinfo[VSC73XX_MAX_NUM_PORTS];
	struct list_head		vlans;
};

/**
@@ -49,6 +71,21 @@ struct vsc73xx_ops {
		     u32 val);
};

/**
 * struct vsc73xx_bridge_vlan - VSC73xx driver structure which keeps vlan
 *	database copy
 * @vid: VLAN number
 * @portmask: each bit represents one port
 * @untagged: each bit represents one port configured with @vid untagged
 * @list: list structure
 */
struct vsc73xx_bridge_vlan {
	u16 vid;
	u8 portmask;
	u8 untagged;
	struct list_head list;
};

int vsc73xx_is_addr_valid(u8 block, u8 subblock);
int vsc73xx_probe(struct vsc73xx *vsc);
void vsc73xx_remove(struct vsc73xx *vsc);
+7 −1
Original line number Diff line number Diff line
@@ -8,12 +8,18 @@
#include <net/dsa.h>
#include <linux/types.h>

/* VBID is limited to three bits only and zero is reserved.
 * Only 7 bridges can be enumerated.
 */
#define DSA_TAG_8021Q_MAX_NUM_BRIDGES	7

int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto);

void dsa_tag_8021q_unregister(struct dsa_switch *ds);

int dsa_tag_8021q_bridge_join(struct dsa_switch *ds, int port,
			      struct dsa_bridge bridge);
			      struct dsa_bridge bridge, bool *tx_fwd_offload,
			      struct netlink_ext_ack *extack);

void dsa_tag_8021q_bridge_leave(struct dsa_switch *ds, int port,
				struct dsa_bridge bridge);
Loading