提交 4314557c 编写于 作者: V Vivien Didelot 提交者: David S. Miller

net: dsa: mv88e6xxx: rework port mode setup

A switch port mode is defined by the association of its egress mode, its
frame mode and if supported or required, the ether type value.

Pack all this in a mv88e6xxx_set_port_mode function and provide helpers
for the Normal Network mode, the DSA mode, and the Ether Type DSA mode,
as well as an helper to setup a port's mode depending on its nature.

Define PORT_ETH_TYPE_DEFAULT for the 0x9100 reset value of port E Type.
Signed-off-by: NVivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 6cd456f3
...@@ -2199,69 +2199,82 @@ static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip) ...@@ -2199,69 +2199,82 @@ static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip)
return err; return err;
} }
static int mv88e6xxx_setup_port_dsa(struct mv88e6xxx_chip *chip, int port, static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
int upstream_port) enum mv88e6xxx_frame_mode frame, u16 egress,
u16 etype)
{ {
int err; int err;
err = chip->info->ops->port_set_frame_mode( if (!chip->info->ops->port_set_frame_mode)
chip, port, MV88E6XXX_FRAME_MODE_DSA); return -EOPNOTSUPP;
err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
if (err) if (err)
return err; return err;
return chip->info->ops->port_set_egress_unknowns( err = chip->info->ops->port_set_frame_mode(chip, port, frame);
chip, port, port == upstream_port); if (err)
return err;
if (chip->info->ops->port_set_ether_type)
return chip->info->ops->port_set_ether_type(chip, port, etype);
return 0;
} }
static int mv88e6xxx_setup_port_cpu(struct mv88e6xxx_chip *chip, int port) static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
{ {
int err; return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
PORT_CONTROL_EGRESS_UNMODIFIED,
PORT_ETH_TYPE_DEFAULT);
}
switch (chip->info->tag_protocol) { static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
case DSA_TAG_PROTO_EDSA: {
err = chip->info->ops->port_set_frame_mode( return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
chip, port, MV88E6XXX_FRAME_MODE_ETHERTYPE); PORT_CONTROL_EGRESS_UNMODIFIED,
if (err) PORT_ETH_TYPE_DEFAULT);
return err; }
err = mv88e6xxx_port_set_egress_mode( static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
chip, port, PORT_CONTROL_EGRESS_ADD_TAG); {
if (err) return mv88e6xxx_set_port_mode(chip, port,
return err; MV88E6XXX_FRAME_MODE_ETHERTYPE,
PORT_CONTROL_EGRESS_ADD_TAG, ETH_P_EDSA);
}
if (chip->info->ops->port_set_ether_type) static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
err = chip->info->ops->port_set_ether_type( {
chip, port, ETH_P_EDSA); if (dsa_is_dsa_port(chip->ds, port))
break; return mv88e6xxx_set_port_mode_dsa(chip, port);
case DSA_TAG_PROTO_DSA: if (dsa_is_normal_port(chip->ds, port))
err = chip->info->ops->port_set_frame_mode( return mv88e6xxx_set_port_mode_normal(chip, port);
chip, port, MV88E6XXX_FRAME_MODE_DSA);
if (err)
return err;
err = mv88e6xxx_port_set_egress_mode( /* Setup CPU port mode depending on its supported tag format */
chip, port, PORT_CONTROL_EGRESS_UNMODIFIED); if (chip->info->tag_protocol == DSA_TAG_PROTO_DSA)
break; return mv88e6xxx_set_port_mode_dsa(chip, port);
default:
err = -EINVAL;
}
if (err) if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
return err; return mv88e6xxx_set_port_mode_edsa(chip, port);
return chip->info->ops->port_set_egress_unknowns(chip, port, true); return -EINVAL;
} }
static int mv88e6xxx_setup_port_normal(struct mv88e6xxx_chip *chip, int port) static int mv88e6xxx_setup_port_dsa(struct mv88e6xxx_chip *chip, int port,
int upstream_port)
{ {
int err; return chip->info->ops->port_set_egress_unknowns(
chip, port, port == upstream_port);
}
err = chip->info->ops->port_set_frame_mode( static int mv88e6xxx_setup_port_cpu(struct mv88e6xxx_chip *chip, int port)
chip, port, MV88E6XXX_FRAME_MODE_NORMAL); {
if (err) return chip->info->ops->port_set_egress_unknowns(chip, port, true);
return err; }
static int mv88e6xxx_setup_port_normal(struct mv88e6xxx_chip *chip, int port)
{
return chip->info->ops->port_set_egress_unknowns(chip, port, false); return chip->info->ops->port_set_egress_unknowns(chip, port, false);
} }
...@@ -2325,6 +2338,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) ...@@ -2325,6 +2338,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
if (err) if (err)
return err; return err;
err = mv88e6xxx_setup_port_mode(chip, port);
if (err)
return err;
/* If this port is connected to a SerDes, make sure the SerDes is not /* If this port is connected to a SerDes, make sure the SerDes is not
* powered down. * powered down.
*/ */
...@@ -3554,11 +3571,6 @@ static const struct mv88e6xxx_ops mv88e6391_ops = { ...@@ -3554,11 +3571,6 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
static int mv88e6xxx_verify_madatory_ops(struct mv88e6xxx_chip *chip, static int mv88e6xxx_verify_madatory_ops(struct mv88e6xxx_chip *chip,
const struct mv88e6xxx_ops *ops) const struct mv88e6xxx_ops *ops)
{ {
if (!ops->port_set_frame_mode) {
dev_err(chip->dev, "Missing port_set_frame_mode");
return -EINVAL;
}
if (!ops->port_set_egress_unknowns) { if (!ops->port_set_egress_unknowns) {
dev_err(chip->dev, "Missing port_set_egress_mode"); dev_err(chip->dev, "Missing port_set_egress_mode");
return -EINVAL; return -EINVAL;
......
...@@ -182,6 +182,7 @@ ...@@ -182,6 +182,7 @@
#define PORT_ATU_CONTROL 0x0c #define PORT_ATU_CONTROL 0x0c
#define PORT_PRI_OVERRIDE 0x0d #define PORT_PRI_OVERRIDE 0x0d
#define PORT_ETH_TYPE 0x0f #define PORT_ETH_TYPE 0x0f
#define PORT_ETH_TYPE_DEFAULT 0x9100
#define PORT_IN_DISCARD_LO 0x10 #define PORT_IN_DISCARD_LO 0x10
#define PORT_IN_DISCARD_HI 0x11 #define PORT_IN_DISCARD_HI 0x11
#define PORT_IN_FILTERED 0x12 #define PORT_IN_FILTERED 0x12
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册