aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-08-17 19:18:34 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-17 19:18:34 -0400
commit647f28c7274a776c3babc3893f530513845b3666 (patch)
treec925e2cd58ce1c426613b7ce967b517b814cfa08
parenta1560dd7a47f983419760aa7f6a481e3b910b54b (diff)
parent9ffcc3725f096e9f0d985f738b0e44214cd72d93 (diff)
Merge branch 'mlxsw-fixes'
Jiri Pirko says: ==================== mlxsw: IPv4 UC router fixes Ido says: Patches 1-3 fix a long standing problem in the driver's init sequence, which manifests itself quite often when routing daemons try to configure an IP address on registered netdevs that don't yet have an associated vPort. Patches 4-9 add missing packet traps for the router to work properly and also fix ordering issue following the recent changes to the driver's init sequence. The last patch isn't related to the router, but fixes a general problem in which under certain conditions packets aren't trapped to CPU. v1->v2: - Change order of patch 7 - Add patch 6 following Ilan's comment - Add patchset name and cover letter ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/reg.h11
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c110
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c42
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/trap.h4
6 files changed, 83 insertions, 88 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 7ca9201f7dcb..1721098eef13 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -3383,6 +3383,15 @@ MLXSW_ITEM32(reg, ritr, ipv4_fe, 0x04, 29, 1);
3383 */ 3383 */
3384MLXSW_ITEM32(reg, ritr, ipv6_fe, 0x04, 28, 1); 3384MLXSW_ITEM32(reg, ritr, ipv6_fe, 0x04, 28, 1);
3385 3385
3386/* reg_ritr_lb_en
3387 * Loop-back filter enable for unicast packets.
3388 * If the flag is set then loop-back filter for unicast packets is
3389 * implemented on the RIF. Multicast packets are always subject to
3390 * loop-back filtering.
3391 * Access: RW
3392 */
3393MLXSW_ITEM32(reg, ritr, lb_en, 0x04, 24, 1);
3394
3386/* reg_ritr_virtual_router 3395/* reg_ritr_virtual_router
3387 * Virtual router ID associated with the router interface. 3396 * Virtual router ID associated with the router interface.
3388 * Access: RW 3397 * Access: RW
@@ -3484,6 +3493,7 @@ static inline void mlxsw_reg_ritr_pack(char *payload, bool enable,
3484 mlxsw_reg_ritr_op_set(payload, op); 3493 mlxsw_reg_ritr_op_set(payload, op);
3485 mlxsw_reg_ritr_rif_set(payload, rif); 3494 mlxsw_reg_ritr_rif_set(payload, rif);
3486 mlxsw_reg_ritr_ipv4_fe_set(payload, 1); 3495 mlxsw_reg_ritr_ipv4_fe_set(payload, 1);
3496 mlxsw_reg_ritr_lb_en_set(payload, 1);
3487 mlxsw_reg_ritr_mtu_set(payload, mtu); 3497 mlxsw_reg_ritr_mtu_set(payload, mtu);
3488 mlxsw_reg_ritr_if_mac_memcpy_to(payload, mac); 3498 mlxsw_reg_ritr_if_mac_memcpy_to(payload, mac);
3489} 3499}
@@ -4000,6 +4010,7 @@ static inline void mlxsw_reg_ralue_pack(char *payload,
4000{ 4010{
4001 MLXSW_REG_ZERO(ralue, payload); 4011 MLXSW_REG_ZERO(ralue, payload);
4002 mlxsw_reg_ralue_protocol_set(payload, protocol); 4012 mlxsw_reg_ralue_protocol_set(payload, protocol);
4013 mlxsw_reg_ralue_op_set(payload, op);
4003 mlxsw_reg_ralue_virtual_router_set(payload, virtual_router); 4014 mlxsw_reg_ralue_virtual_router_set(payload, virtual_router);
4004 mlxsw_reg_ralue_prefix_len_set(payload, prefix_len); 4015 mlxsw_reg_ralue_prefix_len_set(payload, prefix_len);
4005 mlxsw_reg_ralue_entry_type_set(payload, 4016 mlxsw_reg_ralue_entry_type_set(payload,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index e1b8f62ccaed..1fe9fbdc9102 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -942,8 +942,8 @@ static void mlxsw_sp_port_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_vport)
942 kfree(mlxsw_sp_vport); 942 kfree(mlxsw_sp_vport);
943} 943}
944 944
945int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto, 945static int mlxsw_sp_port_add_vid(struct net_device *dev,
946 u16 vid) 946 __be16 __always_unused proto, u16 vid)
947{ 947{
948 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 948 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
949 struct mlxsw_sp_port *mlxsw_sp_vport; 949 struct mlxsw_sp_port *mlxsw_sp_vport;
@@ -956,16 +956,12 @@ int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
956 if (!vid) 956 if (!vid)
957 return 0; 957 return 0;
958 958
959 if (mlxsw_sp_port_vport_find(mlxsw_sp_port, vid)) { 959 if (mlxsw_sp_port_vport_find(mlxsw_sp_port, vid))
960 netdev_warn(dev, "VID=%d already configured\n", vid);
961 return 0; 960 return 0;
962 }
963 961
964 mlxsw_sp_vport = mlxsw_sp_port_vport_create(mlxsw_sp_port, vid); 962 mlxsw_sp_vport = mlxsw_sp_port_vport_create(mlxsw_sp_port, vid);
965 if (!mlxsw_sp_vport) { 963 if (!mlxsw_sp_vport)
966 netdev_err(dev, "Failed to create vPort for VID=%d\n", vid);
967 return -ENOMEM; 964 return -ENOMEM;
968 }
969 965
970 /* When adding the first VLAN interface on a bridged port we need to 966 /* When adding the first VLAN interface on a bridged port we need to
971 * transition all the active 802.1Q bridge VLANs to use explicit 967 * transition all the active 802.1Q bridge VLANs to use explicit
@@ -973,24 +969,17 @@ int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
973 */ 969 */
974 if (list_is_singular(&mlxsw_sp_port->vports_list)) { 970 if (list_is_singular(&mlxsw_sp_port->vports_list)) {
975 err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port); 971 err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
976 if (err) { 972 if (err)
977 netdev_err(dev, "Failed to set to Virtual mode\n");
978 goto err_port_vp_mode_trans; 973 goto err_port_vp_mode_trans;
979 }
980 } 974 }
981 975
982 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false); 976 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
983 if (err) { 977 if (err)
984 netdev_err(dev, "Failed to disable learning for VID=%d\n", vid);
985 goto err_port_vid_learning_set; 978 goto err_port_vid_learning_set;
986 }
987 979
988 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, untagged); 980 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, untagged);
989 if (err) { 981 if (err)
990 netdev_err(dev, "Failed to set VLAN membership for VID=%d\n",
991 vid);
992 goto err_port_add_vid; 982 goto err_port_add_vid;
993 }
994 983
995 return 0; 984 return 0;
996 985
@@ -1010,7 +999,6 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1010 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 999 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1011 struct mlxsw_sp_port *mlxsw_sp_vport; 1000 struct mlxsw_sp_port *mlxsw_sp_vport;
1012 struct mlxsw_sp_fid *f; 1001 struct mlxsw_sp_fid *f;
1013 int err;
1014 1002
1015 /* VLAN 0 is removed from HW filter when device goes down, but 1003 /* VLAN 0 is removed from HW filter when device goes down, but
1016 * it is reserved in our case, so simply return. 1004 * it is reserved in our case, so simply return.
@@ -1019,23 +1007,12 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1019 return 0; 1007 return 0;
1020 1008
1021 mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid); 1009 mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
1022 if (!mlxsw_sp_vport) { 1010 if (WARN_ON(!mlxsw_sp_vport))
1023 netdev_warn(dev, "VID=%d does not exist\n", vid);
1024 return 0; 1011 return 0;
1025 }
1026 1012
1027 err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false); 1013 mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
1028 if (err) {
1029 netdev_err(dev, "Failed to set VLAN membership for VID=%d\n",
1030 vid);
1031 return err;
1032 }
1033 1014
1034 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true); 1015 mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
1035 if (err) {
1036 netdev_err(dev, "Failed to enable learning for VID=%d\n", vid);
1037 return err;
1038 }
1039 1016
1040 /* Drop FID reference. If this was the last reference the 1017 /* Drop FID reference. If this was the last reference the
1041 * resources will be freed. 1018 * resources will be freed.
@@ -1048,13 +1025,8 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1048 * transition all active 802.1Q bridge VLANs to use VID to FID 1025 * transition all active 802.1Q bridge VLANs to use VID to FID
1049 * mappings and set port's mode to VLAN mode. 1026 * mappings and set port's mode to VLAN mode.
1050 */ 1027 */
1051 if (list_is_singular(&mlxsw_sp_port->vports_list)) { 1028 if (list_is_singular(&mlxsw_sp_port->vports_list))
1052 err = mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port); 1029 mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
1053 if (err) {
1054 netdev_err(dev, "Failed to set to VLAN mode\n");
1055 return err;
1056 }
1057 }
1058 1030
1059 mlxsw_sp_port_vport_destroy(mlxsw_sp_vport); 1031 mlxsw_sp_port_vport_destroy(mlxsw_sp_vport);
1060 1032
@@ -2076,6 +2048,18 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
2076 return 0; 2048 return 0;
2077} 2049}
2078 2050
2051static int mlxsw_sp_port_pvid_vport_create(struct mlxsw_sp_port *mlxsw_sp_port)
2052{
2053 mlxsw_sp_port->pvid = 1;
2054
2055 return mlxsw_sp_port_add_vid(mlxsw_sp_port->dev, 0, 1);
2056}
2057
2058static int mlxsw_sp_port_pvid_vport_destroy(struct mlxsw_sp_port *mlxsw_sp_port)
2059{
2060 return mlxsw_sp_port_kill_vid(mlxsw_sp_port->dev, 0, 1);
2061}
2062
2079static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, 2063static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2080 bool split, u8 module, u8 width, u8 lane) 2064 bool split, u8 module, u8 width, u8 lane)
2081{ 2065{
@@ -2191,7 +2175,15 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2191 goto err_port_dcb_init; 2175 goto err_port_dcb_init;
2192 } 2176 }
2193 2177
2178 err = mlxsw_sp_port_pvid_vport_create(mlxsw_sp_port);
2179 if (err) {
2180 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to create PVID vPort\n",
2181 mlxsw_sp_port->local_port);
2182 goto err_port_pvid_vport_create;
2183 }
2184
2194 mlxsw_sp_port_switchdev_init(mlxsw_sp_port); 2185 mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
2186 mlxsw_sp->ports[local_port] = mlxsw_sp_port;
2195 err = register_netdev(dev); 2187 err = register_netdev(dev);
2196 if (err) { 2188 if (err) {
2197 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register netdev\n", 2189 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register netdev\n",
@@ -2208,18 +2200,15 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2208 goto err_core_port_init; 2200 goto err_core_port_init;
2209 } 2201 }
2210 2202
2211 err = mlxsw_sp_port_vlan_init(mlxsw_sp_port);
2212 if (err)
2213 goto err_port_vlan_init;
2214
2215 mlxsw_sp->ports[local_port] = mlxsw_sp_port;
2216 return 0; 2203 return 0;
2217 2204
2218err_port_vlan_init:
2219 mlxsw_core_port_fini(&mlxsw_sp_port->core_port);
2220err_core_port_init: 2205err_core_port_init:
2221 unregister_netdev(dev); 2206 unregister_netdev(dev);
2222err_register_netdev: 2207err_register_netdev:
2208 mlxsw_sp->ports[local_port] = NULL;
2209 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
2210 mlxsw_sp_port_pvid_vport_destroy(mlxsw_sp_port);
2211err_port_pvid_vport_create:
2223 mlxsw_sp_port_dcb_fini(mlxsw_sp_port); 2212 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
2224err_port_dcb_init: 2213err_port_dcb_init:
2225err_port_ets_init: 2214err_port_ets_init:
@@ -2227,6 +2216,7 @@ err_port_buffers_init:
2227err_port_admin_status_set: 2216err_port_admin_status_set:
2228err_port_mtu_set: 2217err_port_mtu_set:
2229err_port_speed_by_width_set: 2218err_port_speed_by_width_set:
2219 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
2230err_port_swid_set: 2220err_port_swid_set:
2231err_port_system_port_mapping_set: 2221err_port_system_port_mapping_set:
2232err_dev_addr_init: 2222err_dev_addr_init:
@@ -2246,12 +2236,12 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
2246 2236
2247 if (!mlxsw_sp_port) 2237 if (!mlxsw_sp_port)
2248 return; 2238 return;
2249 mlxsw_sp->ports[local_port] = NULL;
2250 mlxsw_core_port_fini(&mlxsw_sp_port->core_port); 2239 mlxsw_core_port_fini(&mlxsw_sp_port->core_port);
2251 unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */ 2240 unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
2252 mlxsw_sp_port_dcb_fini(mlxsw_sp_port); 2241 mlxsw_sp->ports[local_port] = NULL;
2253 mlxsw_sp_port_kill_vid(mlxsw_sp_port->dev, 0, 1);
2254 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port); 2242 mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
2243 mlxsw_sp_port_pvid_vport_destroy(mlxsw_sp_port);
2244 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
2255 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); 2245 mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
2256 mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port); 2246 mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port);
2257 free_percpu(mlxsw_sp_port->pcpu_stats); 2247 free_percpu(mlxsw_sp_port->pcpu_stats);
@@ -2663,6 +2653,26 @@ static const struct mlxsw_rx_listener mlxsw_sp_rx_listener[] = {
2663 { 2653 {
2664 .func = mlxsw_sp_rx_listener_func, 2654 .func = mlxsw_sp_rx_listener_func,
2665 .local_port = MLXSW_PORT_DONT_CARE, 2655 .local_port = MLXSW_PORT_DONT_CARE,
2656 .trap_id = MLXSW_TRAP_ID_MTUERROR,
2657 },
2658 {
2659 .func = mlxsw_sp_rx_listener_func,
2660 .local_port = MLXSW_PORT_DONT_CARE,
2661 .trap_id = MLXSW_TRAP_ID_TTLERROR,
2662 },
2663 {
2664 .func = mlxsw_sp_rx_listener_func,
2665 .local_port = MLXSW_PORT_DONT_CARE,
2666 .trap_id = MLXSW_TRAP_ID_LBERROR,
2667 },
2668 {
2669 .func = mlxsw_sp_rx_listener_func,
2670 .local_port = MLXSW_PORT_DONT_CARE,
2671 .trap_id = MLXSW_TRAP_ID_OSPF,
2672 },
2673 {
2674 .func = mlxsw_sp_rx_listener_func,
2675 .local_port = MLXSW_PORT_DONT_CARE,
2666 .trap_id = MLXSW_TRAP_ID_IP2ME, 2676 .trap_id = MLXSW_TRAP_ID_IP2ME,
2667 }, 2677 },
2668 { 2678 {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index f69aa37d1521..ab3feb81bd43 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -536,8 +536,6 @@ int mlxsw_sp_port_vid_to_fid_set(struct mlxsw_sp_port *mlxsw_sp_port,
536 u16 vid); 536 u16 vid);
537int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin, 537int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
538 u16 vid_end, bool is_member, bool untagged); 538 u16 vid_end, bool is_member, bool untagged);
539int mlxsw_sp_port_add_vid(struct net_device *dev, __be16 __always_unused proto,
540 u16 vid);
541int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid, 539int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
542 bool set); 540 bool set);
543void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port); 541void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
index 074cdda7b6f3..237418a0e6e0 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
@@ -330,7 +330,7 @@ static const struct mlxsw_sp_sb_cm mlxsw_sp_cpu_port_sb_cms[] = {
330 MLXSW_SP_CPU_PORT_SB_CM, 330 MLXSW_SP_CPU_PORT_SB_CM,
331 MLXSW_SP_CPU_PORT_SB_CM, 331 MLXSW_SP_CPU_PORT_SB_CM,
332 MLXSW_SP_CPU_PORT_SB_CM, 332 MLXSW_SP_CPU_PORT_SB_CM,
333 MLXSW_SP_CPU_PORT_SB_CM, 333 MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(10000), 0, 0),
334 MLXSW_SP_CPU_PORT_SB_CM, 334 MLXSW_SP_CPU_PORT_SB_CM,
335 MLXSW_SP_CPU_PORT_SB_CM, 335 MLXSW_SP_CPU_PORT_SB_CM,
336 MLXSW_SP_CPU_PORT_SB_CM, 336 MLXSW_SP_CPU_PORT_SB_CM,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index a1ad5e6bdfa8..d1b59cdfacc1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -450,6 +450,8 @@ void mlxsw_sp_fid_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *f)
450 450
451 kfree(f); 451 kfree(f);
452 452
453 mlxsw_sp_fid_map(mlxsw_sp, fid, false);
454
453 mlxsw_sp_fid_op(mlxsw_sp, fid, false); 455 mlxsw_sp_fid_op(mlxsw_sp, fid, false);
454} 456}
455 457
@@ -997,13 +999,13 @@ static int mlxsw_sp_port_obj_add(struct net_device *dev,
997} 999}
998 1000
999static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, 1001static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
1000 u16 vid_begin, u16 vid_end, bool init) 1002 u16 vid_begin, u16 vid_end)
1001{ 1003{
1002 struct net_device *dev = mlxsw_sp_port->dev; 1004 struct net_device *dev = mlxsw_sp_port->dev;
1003 u16 vid, pvid; 1005 u16 vid, pvid;
1004 int err; 1006 int err;
1005 1007
1006 if (!init && !mlxsw_sp_port->bridged) 1008 if (!mlxsw_sp_port->bridged)
1007 return -EINVAL; 1009 return -EINVAL;
1008 1010
1009 err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end, 1011 err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end,
@@ -1014,9 +1016,6 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
1014 return err; 1016 return err;
1015 } 1017 }
1016 1018
1017 if (init)
1018 goto out;
1019
1020 pvid = mlxsw_sp_port->pvid; 1019 pvid = mlxsw_sp_port->pvid;
1021 if (pvid >= vid_begin && pvid <= vid_end) { 1020 if (pvid >= vid_begin && pvid <= vid_end) {
1022 err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0); 1021 err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
@@ -1028,7 +1027,6 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
1028 1027
1029 mlxsw_sp_port_fid_leave(mlxsw_sp_port, vid_begin, vid_end); 1028 mlxsw_sp_port_fid_leave(mlxsw_sp_port, vid_begin, vid_end);
1030 1029
1031out:
1032 /* Changing activity bits only if HW operation succeded */ 1030 /* Changing activity bits only if HW operation succeded */
1033 for (vid = vid_begin; vid <= vid_end; vid++) 1031 for (vid = vid_begin; vid <= vid_end; vid++)
1034 clear_bit(vid, mlxsw_sp_port->active_vlans); 1032 clear_bit(vid, mlxsw_sp_port->active_vlans);
@@ -1039,8 +1037,8 @@ out:
1039static int mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, 1037static int mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
1040 const struct switchdev_obj_port_vlan *vlan) 1038 const struct switchdev_obj_port_vlan *vlan)
1041{ 1039{
1042 return __mlxsw_sp_port_vlans_del(mlxsw_sp_port, 1040 return __mlxsw_sp_port_vlans_del(mlxsw_sp_port, vlan->vid_begin,
1043 vlan->vid_begin, vlan->vid_end, false); 1041 vlan->vid_end);
1044} 1042}
1045 1043
1046void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port) 1044void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port)
@@ -1048,7 +1046,7 @@ void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port)
1048 u16 vid; 1046 u16 vid;
1049 1047
1050 for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) 1048 for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID)
1051 __mlxsw_sp_port_vlans_del(mlxsw_sp_port, vid, vid, false); 1049 __mlxsw_sp_port_vlans_del(mlxsw_sp_port, vid, vid);
1052} 1050}
1053 1051
1054static int 1052static int
@@ -1546,32 +1544,6 @@ void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
1546 mlxsw_sp_fdb_fini(mlxsw_sp); 1544 mlxsw_sp_fdb_fini(mlxsw_sp);
1547} 1545}
1548 1546
1549int mlxsw_sp_port_vlan_init(struct mlxsw_sp_port *mlxsw_sp_port)
1550{
1551 struct net_device *dev = mlxsw_sp_port->dev;
1552 int err;
1553
1554 /* Allow only untagged packets to ingress and tag them internally
1555 * with VID 1.
1556 */
1557 mlxsw_sp_port->pvid = 1;
1558 err = __mlxsw_sp_port_vlans_del(mlxsw_sp_port, 0, VLAN_N_VID - 1,
1559 true);
1560 if (err) {
1561 netdev_err(dev, "Unable to init VLANs\n");
1562 return err;
1563 }
1564
1565 /* Add implicit VLAN interface in the device, so that untagged
1566 * packets will be classified to the default vFID.
1567 */
1568 err = mlxsw_sp_port_add_vid(dev, 0, 1);
1569 if (err)
1570 netdev_err(dev, "Failed to configure default vFID\n");
1571
1572 return err;
1573}
1574
1575void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port) 1547void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port)
1576{ 1548{
1577 mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops; 1549 mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/trap.h b/drivers/net/ethernet/mellanox/mlxsw/trap.h
index 470d7696e9fe..ed8e30186400 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/trap.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/trap.h
@@ -56,6 +56,10 @@ enum {
56 MLXSW_TRAP_ID_IGMP_V3_REPORT = 0x34, 56 MLXSW_TRAP_ID_IGMP_V3_REPORT = 0x34,
57 MLXSW_TRAP_ID_ARPBC = 0x50, 57 MLXSW_TRAP_ID_ARPBC = 0x50,
58 MLXSW_TRAP_ID_ARPUC = 0x51, 58 MLXSW_TRAP_ID_ARPUC = 0x51,
59 MLXSW_TRAP_ID_MTUERROR = 0x52,
60 MLXSW_TRAP_ID_TTLERROR = 0x53,
61 MLXSW_TRAP_ID_LBERROR = 0x54,
62 MLXSW_TRAP_ID_OSPF = 0x55,
59 MLXSW_TRAP_ID_IP2ME = 0x5F, 63 MLXSW_TRAP_ID_IP2ME = 0x5F,
60 MLXSW_TRAP_ID_RTR_INGRESS0 = 0x70, 64 MLXSW_TRAP_ID_RTR_INGRESS0 = 0x70,
61 MLXSW_TRAP_ID_HOST_MISS_IPV4 = 0x90, 65 MLXSW_TRAP_ID_HOST_MISS_IPV4 = 0x90,