spectrum: Add a delayed work to update SPAN buffsize according to speed
authorJiri Pirko <jiri@mellanox.com>
Mon, 20 Jan 2020 07:52:53 +0000 (09:52 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jan 2020 12:25:46 +0000 (13:25 +0100)
When PUDE event is handled and the link is up, update the port SPAN
buffer size according to the current speed.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h

index f6d2c6f6889fefc02007eda198c451107ff33451..9eb3ac7669f7d2560be611daf4dcca4359bd8a0e 100644 (file)
@@ -3908,6 +3908,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
 
        INIT_DELAYED_WORK(&mlxsw_sp_port->ptp.shaper_dw,
                          mlxsw_sp->ptp_ops->shaper_work);
+       INIT_DELAYED_WORK(&mlxsw_sp_port->span.speed_update_dw,
+                         mlxsw_sp_span_speed_update_work);
 
        mlxsw_sp->ports[local_port] = mlxsw_sp_port;
        err = register_netdev(dev);
@@ -3964,6 +3966,7 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
 
        cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw);
+       cancel_delayed_work_sync(&mlxsw_sp_port->span.speed_update_dw);
        cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw);
        mlxsw_sp_port_ptp_clear(mlxsw_sp_port);
        mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
@@ -4371,6 +4374,7 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
                netdev_info(mlxsw_sp_port->dev, "link up\n");
                netif_carrier_on(mlxsw_sp_port->dev);
                mlxsw_core_schedule_dw(&mlxsw_sp_port->ptp.shaper_dw, 0);
+               mlxsw_core_schedule_dw(&mlxsw_sp_port->span.speed_update_dw, 0);
        } else {
                netdev_info(mlxsw_sp_port->dev, "link down\n");
                netif_carrier_off(mlxsw_sp_port->dev);
index 39c3d3ee79a6218059af3f24d4f733f0a1712969..5f3b74360dc88b26febde93cafd11e9bb2cfc13f 100644 (file)
@@ -294,6 +294,9 @@ struct mlxsw_sp_port {
                struct mlxsw_sp_ptp_port_stats stats;
        } ptp;
        u8 split_base_local_port;
+       struct {
+               struct delayed_work speed_update_dw;
+       } span;
 };
 
 struct mlxsw_sp_port_type_speed_ops {
index 88b8edf14387747d245ce5b57a58c5af5b419218..0cdd7954a085fb75fcc00792ac3b9fcf26b2d111 100644 (file)
@@ -778,6 +778,22 @@ int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
        return 0;
 }
 
+void mlxsw_sp_span_speed_update_work(struct work_struct *work)
+{
+       struct delayed_work *dwork = to_delayed_work(work);
+       struct mlxsw_sp_port *mlxsw_sp_port;
+
+       mlxsw_sp_port = container_of(dwork, struct mlxsw_sp_port,
+                                    span.speed_update_dw);
+
+       /* If port is egress mirrored, the shared buffer size should be
+        * updated according to the speed value.
+        */
+       if (mlxsw_sp_span_is_egress_mirror(mlxsw_sp_port))
+               mlxsw_sp_span_port_buffsize_update(mlxsw_sp_port,
+                                                  mlxsw_sp_port->dev->mtu);
+}
+
 static struct mlxsw_sp_span_inspected_port *
 mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry,
                                    enum mlxsw_sp_span_type type,
index 5e04252f2a11706599f0080d0c2008d1a1e0c1dd..59724335525f279b7089ced52670b90d85c2b430 100644 (file)
@@ -74,5 +74,6 @@ void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
                                    struct mlxsw_sp_span_entry *span_entry);
 
 int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
+void mlxsw_sp_span_speed_update_work(struct work_struct *work);
 
 #endif