Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3a2cd32 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: introduce .port_set_policy



Introduce a new .port_set_policy operation to configure a port's
Policy Control List, based on mapping such as DA, SA, Etype and so on.

Models similar to 88E6352 and 88E6390 are supported at the moment.

Signed-off-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d8291a95
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -3132,6 +3132,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
	.port_set_speed = mv88e6352_port_set_speed,
	.port_tag_remap = mv88e6095_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3218,6 +3219,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
	.port_set_speed = mv88e6352_port_set_speed,
	.port_tag_remap = mv88e6095_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3303,6 +3305,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
	.port_set_speed = mv88e6390_port_set_speed,
	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
	.port_tag_remap = mv88e6390_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3351,6 +3354,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
	.port_set_speed = mv88e6390x_port_set_speed,
	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
	.port_tag_remap = mv88e6390_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3448,6 +3452,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
	.port_set_speed = mv88e6352_port_set_speed,
	.port_tag_remap = mv88e6095_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3539,6 +3544,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
	.port_set_speed = mv88e6390_port_set_speed,
	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
	.port_tag_remap = mv88e6390_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3809,6 +3815,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
	.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
	.port_set_speed = mv88e6352_port_set_speed,
	.port_tag_remap = mv88e6095_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3863,6 +3870,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
	.port_set_speed = mv88e6390_port_set_speed,
	.port_max_speed_mode = mv88e6390_port_max_speed_mode,
	.port_tag_remap = mv88e6390_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3915,6 +3923,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
	.port_set_speed = mv88e6390x_port_set_speed,
	.port_max_speed_mode = mv88e6390x_port_max_speed_mode,
	.port_tag_remap = mv88e6390_port_tag_remap,
	.port_set_policy = mv88e6352_port_set_policy,
	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
	.port_set_ether_type = mv88e6351_port_set_ether_type,
+22 −0
Original line number Diff line number Diff line
@@ -189,6 +189,24 @@ struct mv88e6xxx_port_hwtstamp {
	struct hwtstamp_config tstamp_config;
};

enum mv88e6xxx_policy_mapping {
	MV88E6XXX_POLICY_MAPPING_DA,
	MV88E6XXX_POLICY_MAPPING_SA,
	MV88E6XXX_POLICY_MAPPING_VTU,
	MV88E6XXX_POLICY_MAPPING_ETYPE,
	MV88E6XXX_POLICY_MAPPING_PPPOE,
	MV88E6XXX_POLICY_MAPPING_VBAS,
	MV88E6XXX_POLICY_MAPPING_OPT82,
	MV88E6XXX_POLICY_MAPPING_UDP,
};

enum mv88e6xxx_policy_action {
	MV88E6XXX_POLICY_ACTION_NORMAL,
	MV88E6XXX_POLICY_ACTION_MIRROR,
	MV88E6XXX_POLICY_ACTION_TRAP,
	MV88E6XXX_POLICY_ACTION_DISCARD,
};

struct mv88e6xxx_port {
	struct mv88e6xxx_chip *chip;
	int port;
@@ -381,6 +399,10 @@ struct mv88e6xxx_ops {

	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);

	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
			       enum mv88e6xxx_policy_mapping mapping,
			       enum mv88e6xxx_policy_action action);

	int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
				   enum mv88e6xxx_frame_mode mode);
	int (*port_set_egress_floods)(struct mv88e6xxx_chip *chip, int port,
+74 −0
Original line number Diff line number Diff line
@@ -1341,3 +1341,77 @@ int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)

	return 0;
}

/* Offset 0x0E: Policy Control Register */

int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
			      enum mv88e6xxx_policy_mapping mapping,
			      enum mv88e6xxx_policy_action action)
{
	u16 reg, mask, val;
	int shift;
	int err;

	switch (mapping) {
	case MV88E6XXX_POLICY_MAPPING_DA:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_DA_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_SA:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_SA_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_VTU:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_VTU_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_ETYPE:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_PPPOE:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_VBAS:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_OPT82:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK;
		break;
	case MV88E6XXX_POLICY_MAPPING_UDP:
		shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK);
		mask = MV88E6XXX_PORT_POLICY_CTL_UDP_MASK;
		break;
	default:
		return -EOPNOTSUPP;
	}

	switch (action) {
	case MV88E6XXX_POLICY_ACTION_NORMAL:
		val = MV88E6XXX_PORT_POLICY_CTL_NORMAL;
		break;
	case MV88E6XXX_POLICY_ACTION_MIRROR:
		val = MV88E6XXX_PORT_POLICY_CTL_MIRROR;
		break;
	case MV88E6XXX_POLICY_ACTION_TRAP:
		val = MV88E6XXX_PORT_POLICY_CTL_TRAP;
		break;
	case MV88E6XXX_POLICY_ACTION_DISCARD:
		val = MV88E6XXX_PORT_POLICY_CTL_DISCARD;
		break;
	default:
		return -EOPNOTSUPP;
	}

	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_POLICY_CTL, &reg);
	if (err)
		return err;

	reg &= ~mask;
	reg |= (val << shift) & mask;

	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_POLICY_CTL, reg);
}
+16 −1
Original line number Diff line number Diff line
@@ -223,6 +223,18 @@

/* Offset 0x0E: Policy Control Register */
#define MV88E6XXX_PORT_POLICY_CTL		0x0e
#define MV88E6XXX_PORT_POLICY_CTL_DA_MASK	0xc000
#define MV88E6XXX_PORT_POLICY_CTL_SA_MASK	0x3000
#define MV88E6XXX_PORT_POLICY_CTL_VTU_MASK	0x0c00
#define MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK	0x0300
#define MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK	0x00c0
#define MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK	0x0030
#define MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK	0x000c
#define MV88E6XXX_PORT_POLICY_CTL_UDP_MASK	0x0003
#define MV88E6XXX_PORT_POLICY_CTL_NORMAL	0x0000
#define MV88E6XXX_PORT_POLICY_CTL_MIRROR	0x0001
#define MV88E6XXX_PORT_POLICY_CTL_TRAP		0x0002
#define MV88E6XXX_PORT_POLICY_CTL_DISCARD	0x0003

/* Offset 0x0F: Port Special Ether Type */
#define MV88E6XXX_PORT_ETH_TYPE		0x0f
@@ -324,6 +336,9 @@ int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
				     bool unicast, bool multicast);
int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
				     bool unicast, bool multicast);
int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
			      enum mv88e6xxx_policy_mapping mapping,
			      enum mv88e6xxx_policy_action action);
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
				  u16 etype);
int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,