]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
mlxsw: spectrum: Query cell size from firmware
[karo-tx-linux.git] / drivers / net / ethernet / mellanox / mlxsw / spectrum_buffers.c
index 7e67d0e5b7f3649133ed6f568bb78a083ed0d4a6..997189cfe7fd58c7e93419d69cf609420eb1633f 100644 (file)
@@ -162,8 +162,8 @@ static int mlxsw_sp_sb_pm_occ_query(struct mlxsw_sp *mlxsw_sp, u8 local_port,
 }
 
 static const u16 mlxsw_sp_pbs[] = {
-       [0] = 2 * MLXSW_SP_BYTES_TO_CELLS(ETH_FRAME_LEN),
-       [9] = 2 * MLXSW_SP_BYTES_TO_CELLS(MLXSW_PORT_MAX_MTU),
+       [0] = 2 * ETH_FRAME_LEN,
+       [9] = 2 * MLXSW_PORT_MAX_MTU,
 };
 
 #define MLXSW_SP_PBS_LEN ARRAY_SIZE(mlxsw_sp_pbs)
@@ -171,20 +171,22 @@ static const u16 mlxsw_sp_pbs[] = {
 
 static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port)
 {
+       struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
        char pbmc_pl[MLXSW_REG_PBMC_LEN];
        int i;
 
        mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port,
                            0xffff, 0xffff / 2);
        for (i = 0; i < MLXSW_SP_PBS_LEN; i++) {
+               u16 size = mlxsw_sp_bytes_cells(mlxsw_sp, mlxsw_sp_pbs[i]);
+
                if (i == MLXSW_SP_PB_UNUSED)
                        continue;
-               mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, mlxsw_sp_pbs[i]);
+               mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size);
        }
        mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl,
                                         MLXSW_REG_PBMC_PORT_SHARED_BUF_IDX, 0);
-       return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core,
-                              MLXSW_REG(pbmc), pbmc_pl);
+       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
 }
 
 static int mlxsw_sp_port_pb_prio_init(struct mlxsw_sp_port *mlxsw_sp_port)
@@ -237,18 +239,17 @@ static void mlxsw_sp_sb_ports_fini(struct mlxsw_sp *mlxsw_sp)
 
 static const struct mlxsw_sp_sb_pr mlxsw_sp_sb_prs_ingress[] = {
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC,
-                      MLXSW_SP_BYTES_TO_CELLS(MLXSW_SP_SB_PR_INGRESS_SIZE)),
+                      MLXSW_SP_SB_PR_INGRESS_SIZE),
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC, 0),
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC, 0),
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC,
-                      MLXSW_SP_BYTES_TO_CELLS(MLXSW_SP_SB_PR_INGRESS_MNG_SIZE)),
+                      MLXSW_SP_SB_PR_INGRESS_MNG_SIZE),
 };
 
 #define MLXSW_SP_SB_PRS_INGRESS_LEN ARRAY_SIZE(mlxsw_sp_sb_prs_ingress)
 
 static const struct mlxsw_sp_sb_pr mlxsw_sp_sb_prs_egress[] = {
-       MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC,
-                      MLXSW_SP_BYTES_TO_CELLS(MLXSW_SP_SB_PR_EGRESS_SIZE)),
+       MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC, MLXSW_SP_SB_PR_EGRESS_SIZE),
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC, 0),
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC, 0),
        MLXSW_SP_SB_PR(MLXSW_REG_SBPR_MODE_DYNAMIC, 0),
@@ -265,11 +266,9 @@ static int __mlxsw_sp_sb_prs_init(struct mlxsw_sp *mlxsw_sp,
        int err;
 
        for (i = 0; i < prs_len; i++) {
-               const struct mlxsw_sp_sb_pr *pr;
+               u32 size = mlxsw_sp_bytes_cells(mlxsw_sp, prs[i].size);
 
-               pr = &prs[i];
-               err = mlxsw_sp_sb_pr_write(mlxsw_sp, i, dir,
-                                          pr->mode, pr->size);
+               err = mlxsw_sp_sb_pr_write(mlxsw_sp, i, dir, prs[i].mode, size);
                if (err)
                        return err;
        }
@@ -298,7 +297,7 @@ static int mlxsw_sp_sb_prs_init(struct mlxsw_sp *mlxsw_sp)
        }
 
 static const struct mlxsw_sp_sb_cm mlxsw_sp_sb_cms_ingress[] = {
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(10000), 8, 0),
+       MLXSW_SP_SB_CM(10000, 8, 0),
        MLXSW_SP_SB_CM(0, MLXSW_REG_SBXX_DYN_MAX_BUFF_MIN, 0),
        MLXSW_SP_SB_CM(0, MLXSW_REG_SBXX_DYN_MAX_BUFF_MIN, 0),
        MLXSW_SP_SB_CM(0, MLXSW_REG_SBXX_DYN_MAX_BUFF_MIN, 0),
@@ -307,20 +306,20 @@ static const struct mlxsw_sp_sb_cm mlxsw_sp_sb_cms_ingress[] = {
        MLXSW_SP_SB_CM(0, MLXSW_REG_SBXX_DYN_MAX_BUFF_MIN, 0),
        MLXSW_SP_SB_CM(0, MLXSW_REG_SBXX_DYN_MAX_BUFF_MIN, 0),
        MLXSW_SP_SB_CM(0, 0, 0), /* dummy, this PG does not exist */
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(20000), 1, 3),
+       MLXSW_SP_SB_CM(20000, 1, 3),
 };
 
 #define MLXSW_SP_SB_CMS_INGRESS_LEN ARRAY_SIZE(mlxsw_sp_sb_cms_ingress)
 
 static const struct mlxsw_sp_sb_cm mlxsw_sp_sb_cms_egress[] = {
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(1500), 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
+       MLXSW_SP_SB_CM(1500, 9, 0),
        MLXSW_SP_SB_CM(0, 0, 0),
        MLXSW_SP_SB_CM(0, 0, 0),
        MLXSW_SP_SB_CM(0, 0, 0),
@@ -344,7 +343,7 @@ static const struct mlxsw_sp_sb_cm mlxsw_sp_cpu_port_sb_cms[] = {
        MLXSW_SP_CPU_PORT_SB_CM,
        MLXSW_SP_CPU_PORT_SB_CM,
        MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_SB_CM(MLXSW_SP_BYTES_TO_CELLS(10000), 0, 0),
+       MLXSW_SP_SB_CM(10000, 0, 0),
        MLXSW_SP_CPU_PORT_SB_CM,
        MLXSW_SP_CPU_PORT_SB_CM,
        MLXSW_SP_CPU_PORT_SB_CM,
@@ -384,13 +383,17 @@ static int __mlxsw_sp_sb_cms_init(struct mlxsw_sp *mlxsw_sp, u8 local_port,
 
        for (i = 0; i < cms_len; i++) {
                const struct mlxsw_sp_sb_cm *cm;
+               u32 min_buff;
 
                if (i == 8 && dir == MLXSW_REG_SBXX_DIR_INGRESS)
                        continue; /* PG number 8 does not exist, skip it */
                cm = &cms[i];
+               /* All pools are initialized using dynamic thresholds,
+                * therefore 'max_buff' isn't specified in cells.
+                */
+               min_buff = mlxsw_sp_bytes_cells(mlxsw_sp, cm->min_buff);
                err = mlxsw_sp_sb_cm_write(mlxsw_sp, local_port, i, dir,
-                                          cm->min_buff, cm->max_buff,
-                                          cm->pool);
+                                          min_buff, cm->max_buff, cm->pool);
                if (err)
                        return err;
        }
@@ -498,21 +501,21 @@ struct mlxsw_sp_sb_mm {
        }
 
 static const struct mlxsw_sp_sb_mm mlxsw_sp_sb_mms[] = {
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
-       MLXSW_SP_SB_MM(MLXSW_SP_BYTES_TO_CELLS(20000), 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
+       MLXSW_SP_SB_MM(20000, 0xff, 0),
 };
 
 #define MLXSW_SP_SB_MMS_LEN ARRAY_SIZE(mlxsw_sp_sb_mms)
@@ -525,10 +528,15 @@ static int mlxsw_sp_sb_mms_init(struct mlxsw_sp *mlxsw_sp)
 
        for (i = 0; i < MLXSW_SP_SB_MMS_LEN; i++) {
                const struct mlxsw_sp_sb_mm *mc;
+               u32 min_buff;
 
                mc = &mlxsw_sp_sb_mms[i];
-               mlxsw_reg_sbmm_pack(sbmm_pl, i, mc->min_buff,
-                                   mc->max_buff, mc->pool);
+               /* All pools are initialized using dynamic thresholds,
+                * therefore 'max_buff' isn't specified in cells.
+                */
+               min_buff = mlxsw_sp_bytes_cells(mlxsw_sp, mc->min_buff);
+               mlxsw_reg_sbmm_pack(sbmm_pl, i, min_buff, mc->max_buff,
+                                   mc->pool);
                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbmm), sbmm_pl);
                if (err)
                        return err;
@@ -541,6 +549,10 @@ int mlxsw_sp_buffers_init(struct mlxsw_sp *mlxsw_sp)
        u64 sb_size;
        int err;
 
+       if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, CELL_SIZE))
+               return -EIO;
+       mlxsw_sp->sb.cell_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, CELL_SIZE);
+
        if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_BUFFER_SIZE))
                return -EIO;
        sb_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_BUFFER_SIZE);
@@ -627,7 +639,7 @@ int mlxsw_sp_sb_pool_get(struct mlxsw_core *mlxsw_core,
        struct mlxsw_sp_sb_pr *pr = mlxsw_sp_sb_pr_get(mlxsw_sp, pool, dir);
 
        pool_info->pool_type = (enum devlink_sb_pool_type) dir;
-       pool_info->size = MLXSW_SP_CELLS_TO_BYTES(pr->size);
+       pool_info->size = mlxsw_sp_cells_bytes(mlxsw_sp, pr->size);
        pool_info->threshold_type = (enum devlink_sb_threshold_type) pr->mode;
        return 0;
 }
@@ -637,9 +649,9 @@ int mlxsw_sp_sb_pool_set(struct mlxsw_core *mlxsw_core,
                         enum devlink_sb_threshold_type threshold_type)
 {
        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
+       u32 pool_size = mlxsw_sp_bytes_cells(mlxsw_sp, size);
        u8 pool = pool_get(pool_index);
        enum mlxsw_reg_sbxx_dir dir = dir_get(pool_index);
-       u32 pool_size = MLXSW_SP_BYTES_TO_CELLS(size);
        enum mlxsw_reg_sbpr_mode mode;
 
        if (size > MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_BUFFER_SIZE))
@@ -658,7 +670,7 @@ static u32 mlxsw_sp_sb_threshold_out(struct mlxsw_sp *mlxsw_sp, u8 pool,
 
        if (pr->mode == MLXSW_REG_SBPR_MODE_DYNAMIC)
                return max_buff - MLXSW_SP_SB_THRESHOLD_TO_ALPHA_OFFSET;
-       return MLXSW_SP_CELLS_TO_BYTES(max_buff);
+       return mlxsw_sp_cells_bytes(mlxsw_sp, max_buff);
 }
 
 static int mlxsw_sp_sb_threshold_in(struct mlxsw_sp *mlxsw_sp, u8 pool,
@@ -676,7 +688,7 @@ static int mlxsw_sp_sb_threshold_in(struct mlxsw_sp *mlxsw_sp, u8 pool,
                        return -EINVAL;
                *p_max_buff = val;
        } else {
-               *p_max_buff = MLXSW_SP_BYTES_TO_CELLS(threshold);
+               *p_max_buff = mlxsw_sp_bytes_cells(mlxsw_sp, threshold);
        }
        return 0;
 }
@@ -963,8 +975,8 @@ int mlxsw_sp_sb_occ_port_pool_get(struct mlxsw_core_port *mlxsw_core_port,
        struct mlxsw_sp_sb_pm *pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port,
                                                       pool, dir);
 
-       *p_cur = MLXSW_SP_CELLS_TO_BYTES(pm->occ.cur);
-       *p_max = MLXSW_SP_CELLS_TO_BYTES(pm->occ.max);
+       *p_cur = mlxsw_sp_cells_bytes(mlxsw_sp, pm->occ.cur);
+       *p_max = mlxsw_sp_cells_bytes(mlxsw_sp, pm->occ.max);
        return 0;
 }
 
@@ -982,7 +994,7 @@ int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port,
        struct mlxsw_sp_sb_cm *cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port,
                                                       pg_buff, dir);
 
-       *p_cur = MLXSW_SP_CELLS_TO_BYTES(cm->occ.cur);
-       *p_max = MLXSW_SP_CELLS_TO_BYTES(cm->occ.max);
+       *p_cur = mlxsw_sp_cells_bytes(mlxsw_sp, cm->occ.cur);
+       *p_max = mlxsw_sp_cells_bytes(mlxsw_sp, cm->occ.max);
        return 0;
 }