mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-07 15:01:44 +00:00
mlxsw: Make EtherType configurable when pushing VLAN at ingress
Currently, when pushing a PVID at ingress, mlxsw always uses 802.1q EtherType. Make this EtherType configurable by extending mlxsw_sp_port_pvid_set() with an EtherType argument. This is a preparation for QinQ support, that needs to push a PVID with 802.1ad EtherType. Signed-off-by: Amit Cohen <amcohen@nvidia.com> Reviewed-by: Petr Machata <petrm@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a2ef3ae158
commit
3ae7a65b64
4 changed files with 48 additions and 13 deletions
|
@ -851,11 +851,13 @@ MLXSW_ITEM32(reg, spvid, et_vlan, 0x04, 16, 2);
|
||||||
*/
|
*/
|
||||||
MLXSW_ITEM32(reg, spvid, pvid, 0x04, 0, 12);
|
MLXSW_ITEM32(reg, spvid, pvid, 0x04, 0, 12);
|
||||||
|
|
||||||
static inline void mlxsw_reg_spvid_pack(char *payload, u8 local_port, u16 pvid)
|
static inline void mlxsw_reg_spvid_pack(char *payload, u8 local_port, u16 pvid,
|
||||||
|
u8 et_vlan)
|
||||||
{
|
{
|
||||||
MLXSW_REG_ZERO(spvid, payload);
|
MLXSW_REG_ZERO(spvid, payload);
|
||||||
mlxsw_reg_spvid_local_port_set(payload, local_port);
|
mlxsw_reg_spvid_local_port_set(payload, local_port);
|
||||||
mlxsw_reg_spvid_pvid_set(payload, pvid);
|
mlxsw_reg_spvid_pvid_set(payload, pvid);
|
||||||
|
mlxsw_reg_spvid_et_vlan_set(payload, et_vlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SPVM - Switch Port VLAN Membership
|
/* SPVM - Switch Port VLAN Membership
|
||||||
|
|
|
@ -384,13 +384,37 @@ int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type)
|
||||||
|
{
|
||||||
|
switch (ethtype) {
|
||||||
|
case ETH_P_8021Q:
|
||||||
|
*p_sver_type = 0;
|
||||||
|
break;
|
||||||
|
case ETH_P_8021AD:
|
||||||
|
*p_sver_type = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int __mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
static int __mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
u16 vid)
|
u16 vid, u16 ethtype)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||||
char spvid_pl[MLXSW_REG_SPVID_LEN];
|
char spvid_pl[MLXSW_REG_SPVID_LEN];
|
||||||
|
u8 sver_type;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = mlxsw_sp_ethtype_to_sver_type(ethtype, &sver_type);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
mlxsw_reg_spvid_pack(spvid_pl, mlxsw_sp_port->local_port, vid,
|
||||||
|
sver_type);
|
||||||
|
|
||||||
mlxsw_reg_spvid_pack(spvid_pl, mlxsw_sp_port->local_port, vid);
|
|
||||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +428,8 @@ static int mlxsw_sp_port_allow_untagged_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spaft), spaft_pl);
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spaft), spaft_pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
|
||||||
|
u16 ethtype)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -413,7 +438,7 @@ int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
} else {
|
} else {
|
||||||
err = __mlxsw_sp_port_pvid_set(mlxsw_sp_port, vid);
|
err = __mlxsw_sp_port_pvid_set(mlxsw_sp_port, vid, ethtype);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, true);
|
err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, true);
|
||||||
|
@ -425,7 +450,7 @@ int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_port_allow_untagged_set:
|
err_port_allow_untagged_set:
|
||||||
__mlxsw_sp_port_pvid_set(mlxsw_sp_port, mlxsw_sp_port->pvid);
|
__mlxsw_sp_port_pvid_set(mlxsw_sp_port, mlxsw_sp_port->pvid, ethtype);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1588,7 +1613,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||||
goto err_port_nve_init;
|
goto err_port_nve_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID);
|
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID,
|
||||||
|
ETH_P_8021Q);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set PVID\n",
|
dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set PVID\n",
|
||||||
mlxsw_sp_port->local_port);
|
mlxsw_sp_port->local_port);
|
||||||
|
@ -3644,7 +3670,8 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
lag->ref_count--;
|
lag->ref_count--;
|
||||||
|
|
||||||
/* Make sure untagged frames are allowed to ingress */
|
/* Make sure untagged frames are allowed to ingress */
|
||||||
mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID);
|
mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID,
|
||||||
|
ETH_P_8021Q);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
|
|
|
@ -580,7 +580,8 @@ int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
|
||||||
int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable);
|
int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable);
|
||||||
int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
|
int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
|
||||||
bool learn_enable);
|
bool learn_enable);
|
||||||
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid);
|
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
|
||||||
|
u16 ethtype);
|
||||||
struct mlxsw_sp_port_vlan *
|
struct mlxsw_sp_port_vlan *
|
||||||
mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid);
|
mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid);
|
||||||
void mlxsw_sp_port_vlan_destroy(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
|
void mlxsw_sp_port_vlan_destroy(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
|
||||||
|
|
|
@ -1129,6 +1129,7 @@ mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
u16 pvid = mlxsw_sp_port_pvid_determine(mlxsw_sp_port, vid, is_pvid);
|
u16 pvid = mlxsw_sp_port_pvid_determine(mlxsw_sp_port, vid, is_pvid);
|
||||||
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
|
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
|
||||||
u16 old_pvid = mlxsw_sp_port->pvid;
|
u16 old_pvid = mlxsw_sp_port->pvid;
|
||||||
|
u16 proto;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* The only valid scenario in which a port-vlan already exists, is if
|
/* The only valid scenario in which a port-vlan already exists, is if
|
||||||
|
@ -1152,7 +1153,8 @@ mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
if (err)
|
if (err)
|
||||||
goto err_port_vlan_set;
|
goto err_port_vlan_set;
|
||||||
|
|
||||||
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, pvid);
|
br_vlan_get_proto(bridge_port->bridge_device->dev, &proto);
|
||||||
|
err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, pvid, proto);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_port_pvid_set;
|
goto err_port_pvid_set;
|
||||||
|
|
||||||
|
@ -1164,7 +1166,7 @@ mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_port_vlan_bridge_join:
|
err_port_vlan_bridge_join:
|
||||||
mlxsw_sp_port_pvid_set(mlxsw_sp_port, old_pvid);
|
mlxsw_sp_port_pvid_set(mlxsw_sp_port, old_pvid, proto);
|
||||||
err_port_pvid_set:
|
err_port_pvid_set:
|
||||||
mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
|
mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
|
||||||
err_port_vlan_set:
|
err_port_vlan_set:
|
||||||
|
@ -1821,13 +1823,15 @@ mlxsw_sp_bridge_port_vlan_del(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
{
|
{
|
||||||
u16 pvid = mlxsw_sp_port->pvid == vid ? 0 : mlxsw_sp_port->pvid;
|
u16 pvid = mlxsw_sp_port->pvid == vid ? 0 : mlxsw_sp_port->pvid;
|
||||||
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
|
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
|
||||||
|
u16 proto;
|
||||||
|
|
||||||
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
|
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
|
||||||
if (WARN_ON(!mlxsw_sp_port_vlan))
|
if (WARN_ON(!mlxsw_sp_port_vlan))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
|
mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
|
||||||
mlxsw_sp_port_pvid_set(mlxsw_sp_port, pvid);
|
br_vlan_get_proto(bridge_port->bridge_device->dev, &proto);
|
||||||
|
mlxsw_sp_port_pvid_set(mlxsw_sp_port, pvid, proto);
|
||||||
mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
|
mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
|
||||||
mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
|
mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
|
||||||
}
|
}
|
||||||
|
@ -1998,7 +2002,8 @@ mlxsw_sp_bridge_8021q_port_leave(struct mlxsw_sp_bridge_device *bridge_device,
|
||||||
struct mlxsw_sp_port *mlxsw_sp_port)
|
struct mlxsw_sp_port *mlxsw_sp_port)
|
||||||
{
|
{
|
||||||
/* Make sure untagged frames are allowed to ingress */
|
/* Make sure untagged frames are allowed to ingress */
|
||||||
mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID);
|
mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID,
|
||||||
|
ETH_P_8021Q);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue