diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index b08853f71b2beae79e1458e2fc2cb77eb6d4dec5..ee0c4d098c7891d762e577ed8ca4cc02893c2b51 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1386,6 +1386,19 @@ static int mlxsw_sp_port_overheat_init_val_set(struct mlxsw_sp_port *mlxsw_sp_po return 0; } +static int +mlxsw_sp_port_vlan_classification_set(struct mlxsw_sp_port *mlxsw_sp_port, + bool is_8021ad_tagged, + bool is_8021q_tagged) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + char spvc_pl[MLXSW_REG_SPVC_LEN]; + + mlxsw_reg_spvc_pack(spvc_pl, mlxsw_sp_port->local_port, + is_8021ad_tagged, is_8021q_tagged); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvc), spvc_pl); +} + static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 split_base_local_port, struct mlxsw_sp_port_mapping *port_mapping) @@ -1592,6 +1605,16 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, } mlxsw_sp_port->default_vlan = mlxsw_sp_port_vlan; + /* Set SPVC.et0=true and SPVC.et1=false to make the local port to treat + * only packets with 802.1q header as tagged packets. + */ + err = mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, false, true); + if (err) { + dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set default VLAN classification\n", + local_port); + goto err_port_vlan_classification_set; + } + INIT_DELAYED_WORK(&mlxsw_sp_port->ptp.shaper_dw, mlxsw_sp->ptp_ops->shaper_work); @@ -1618,6 +1641,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, err_register_netdev: err_port_overheat_init_val_set: + mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, true, true); +err_port_vlan_classification_set: mlxsw_sp->ports[local_port] = NULL; mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan); err_port_vlan_create: @@ -1664,6 +1689,7 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) mlxsw_sp_port_ptp_clear(mlxsw_sp_port); mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp); unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */ + mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, true, true); mlxsw_sp->ports[local_port] = NULL; mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true); mlxsw_sp_port_nve_fini(mlxsw_sp_port);