.sample_del = mlxsw_sp1_mall_sample_del,
 };
 
+static int mlxsw_sp2_mall_sample_add(struct mlxsw_sp *mlxsw_sp,
+                                    struct mlxsw_sp_port *mlxsw_sp_port,
+                                    u32 rate)
+{
+       struct mlxsw_sp_span_trigger_parms trigger_parms = {};
+       struct mlxsw_sp_span_agent_parms agent_parms = {
+               .to_dev = NULL, /* Mirror to CPU. */
+               .session_id = MLXSW_SP_SPAN_SESSION_ID_SAMPLING,
+       };
+       struct mlxsw_sp_port_sample *sample;
+       int err;
+
+       sample = rtnl_dereference(mlxsw_sp_port->sample);
+
+       err = mlxsw_sp_span_agent_get(mlxsw_sp, &sample->span_id, &agent_parms);
+       if (err)
+               return err;
+
+       err = mlxsw_sp_span_analyzed_port_get(mlxsw_sp_port, true);
+       if (err)
+               goto err_analyzed_port_get;
+
+       trigger_parms.span_id = sample->span_id;
+       trigger_parms.probability_rate = rate;
+       err = mlxsw_sp_span_agent_bind(mlxsw_sp, MLXSW_SP_SPAN_TRIGGER_INGRESS,
+                                      mlxsw_sp_port, &trigger_parms);
+       if (err)
+               goto err_agent_bind;
+
+       return 0;
+
+err_agent_bind:
+       mlxsw_sp_span_analyzed_port_put(mlxsw_sp_port, true);
+err_analyzed_port_get:
+       mlxsw_sp_span_agent_put(mlxsw_sp, sample->span_id);
+       return err;
+}
+
+static void mlxsw_sp2_mall_sample_del(struct mlxsw_sp *mlxsw_sp,
+                                     struct mlxsw_sp_port *mlxsw_sp_port)
+{
+       struct mlxsw_sp_span_trigger_parms trigger_parms = {};
+       struct mlxsw_sp_port_sample *sample;
+
+       sample = rtnl_dereference(mlxsw_sp_port->sample);
+
+       trigger_parms.span_id = sample->span_id;
+       mlxsw_sp_span_agent_unbind(mlxsw_sp, MLXSW_SP_SPAN_TRIGGER_INGRESS,
+                                  mlxsw_sp_port, &trigger_parms);
+       mlxsw_sp_span_analyzed_port_put(mlxsw_sp_port, true);
+       mlxsw_sp_span_agent_put(mlxsw_sp, sample->span_id);
+}
+
 const struct mlxsw_sp_mall_ops mlxsw_sp2_mall_ops = {
-       .sample_add = mlxsw_sp1_mall_sample_add,
-       .sample_del = mlxsw_sp1_mall_sample_del,
+       .sample_add = mlxsw_sp2_mall_sample_add,
+       .sample_del = mlxsw_sp2_mall_sample_del,
 };
 
 #define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
 
 enum {
+       /* Packet was mirrored from ingress. */
+       MLXSW_SP_MIRROR_REASON_INGRESS = 1,
        /* Packet was early dropped. */
        MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9,
 };
                .group = DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),
                .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_PKT_SAMPLE,
                .priority = 0,
+               .fixed_policer = true,
        },
 };
 
                .trap = MLXSW_SP_TRAP_CONTROL(FLOW_ACTION_SAMPLE, ACL_SAMPLE,
                                              MIRROR),
                .listeners_arr = {
-                       MLXSW_RXL(mlxsw_sp_rx_sample_listener, PKT_SAMPLE,
-                                 MIRROR_TO_CPU, false, SP_PKT_SAMPLE, DISCARD),
+                       MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_listener, 1,
+                                        SP_PKT_SAMPLE,
+                                        MLXSW_SP_MIRROR_REASON_INGRESS),
                },
        },
 };