mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer
authorShalom Toledo <shalomt@mellanox.com>
Mon, 16 Sep 2019 15:04:22 +0000 (18:04 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 16 Sep 2019 20:07:59 +0000 (22:07 +0200)
While debugging packet loss towards the CPU, it is useful to be able to
query the CPU port's shared buffer quotas and occupancy.

Since the CPU port has no ingress buffers, all the shared buffers ingress
information will be cleared.

Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
Acked-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_buffers.c

index f1dbde73fa789abff6f35be5291d9d5792448cb9..b9eeae37a4dcfe00e3b363575c14fe48155fed7f 100644 (file)
@@ -250,6 +250,10 @@ static int mlxsw_sp_sb_pm_occ_clear(struct mlxsw_sp *mlxsw_sp, u8 local_port,
                &mlxsw_sp->sb_vals->pool_dess[pool_index];
        char sbpm_pl[MLXSW_REG_SBPM_LEN];
 
+       if (local_port == MLXSW_PORT_CPU_PORT &&
+           des->dir == MLXSW_REG_SBXX_DIR_INGRESS)
+               return 0;
+
        mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir,
                            true, 0, 0);
        return mlxsw_reg_trans_query(mlxsw_sp->core, MLXSW_REG(sbpm), sbpm_pl,
@@ -273,6 +277,10 @@ static int mlxsw_sp_sb_pm_occ_query(struct mlxsw_sp *mlxsw_sp, u8 local_port,
        char sbpm_pl[MLXSW_REG_SBPM_LEN];
        struct mlxsw_sp_sb_pm *pm;
 
+       if (local_port == MLXSW_PORT_CPU_PORT &&
+           des->dir == MLXSW_REG_SBXX_DIR_INGRESS)
+               return 0;
+
        pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port, pool_index);
        mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir,
                            false, 0, 0);
@@ -1197,6 +1205,11 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core,
             local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
                if (!mlxsw_sp->ports[local_port])
                        continue;
+               if (local_port == MLXSW_PORT_CPU_PORT) {
+                       /* Ingress quotas are not supported for the CPU port */
+                       masked_count++;
+                       continue;
+               }
                for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) {
                        cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, i,
                                                MLXSW_REG_SBXX_DIR_INGRESS);
@@ -1232,7 +1245,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
        char *sbsr_pl;
        u8 masked_count;
        u8 local_port_1;
-       u8 local_port = 0;
+       u8 local_port;
        int i;
        int err;
        int err2;
@@ -1241,8 +1254,8 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
        if (!sbsr_pl)
                return -ENOMEM;
 
+       local_port = MLXSW_PORT_CPU_PORT;
 next_batch:
-       local_port++;
        local_port_1 = local_port;
        masked_count = 0;
        mlxsw_reg_sbsr_pack(sbsr_pl, false);
@@ -1253,7 +1266,11 @@ next_batch:
        for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
                if (!mlxsw_sp->ports[local_port])
                        continue;
-               mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1);
+               if (local_port != MLXSW_PORT_CPU_PORT) {
+                       /* Ingress quotas are not supported for the CPU port */
+                       mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
+                                                            local_port, 1);
+               }
                mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
                for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
                        err = mlxsw_sp_sb_pm_occ_query(mlxsw_sp, local_port, i,
@@ -1274,8 +1291,10 @@ do_query:
                                    cb_priv);
        if (err)
                goto out;
-       if (local_port < mlxsw_core_max_ports(mlxsw_core))
+       if (local_port < mlxsw_core_max_ports(mlxsw_core)) {
+               local_port++;
                goto next_batch;
+       }
 
 out:
        err2 = mlxsw_reg_trans_bulk_wait(&bulk_list);
@@ -1292,7 +1311,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
        LIST_HEAD(bulk_list);
        char *sbsr_pl;
        unsigned int masked_count;
-       u8 local_port = 0;
+       u8 local_port;
        int i;
        int err;
        int err2;
@@ -1301,8 +1320,8 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
        if (!sbsr_pl)
                return -ENOMEM;
 
+       local_port = MLXSW_PORT_CPU_PORT;
 next_batch:
-       local_port++;
        masked_count = 0;
        mlxsw_reg_sbsr_pack(sbsr_pl, true);
        for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++)
@@ -1312,7 +1331,11 @@ next_batch:
        for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
                if (!mlxsw_sp->ports[local_port])
                        continue;
-               mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1);
+               if (local_port != MLXSW_PORT_CPU_PORT) {
+                       /* Ingress quotas are not supported for the CPU port */
+                       mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
+                                                            local_port, 1);
+               }
                mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
                for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
                        err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i,
@@ -1329,8 +1352,10 @@ do_query:
                                    &bulk_list, NULL, 0);
        if (err)
                goto out;
-       if (local_port < mlxsw_core_max_ports(mlxsw_core))
+       if (local_port < mlxsw_core_max_ports(mlxsw_core)) {
+               local_port++;
                goto next_batch;
+       }
 
 out:
        err2 = mlxsw_reg_trans_bulk_wait(&bulk_list);