static int mlxsw_sp_sb_cm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 pg_buff, u32 min_buff, u32 max_buff, bool infi_max, u16 pool_index) { const struct mlxsw_sp_sb_pool_des *des = &mlxsw_sp->sb_vals->pool_dess[pool_index]; char sbcm_pl[MLXSW_REG_SBCM_LEN]; struct mlxsw_sp_sb_cm *cm; int err; mlxsw_reg_sbcm_pack(sbcm_pl, local_port, pg_buff, des->dir, min_buff, max_buff, infi_max, des->pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbcm), sbcm_pl); if (err) return err; if (mlxsw_sp_sb_cm_exists(pg_buff, des->dir)) { if (infi_max) max_buff = mlxsw_sp_bytes_cells(mlxsw_sp, mlxsw_sp->sb->sb_size); cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, pg_buff, des->dir); cm->min_buff = min_buff; cm->max_buff = max_buff; cm->pool_index = pool_index; } return 0; }
static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core, char *sbsr_pl, size_t sbsr_pl_len, unsigned long cb_priv) { struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp_sb_sr_occ_query_cb_ctx cb_ctx; u8 masked_count; u8 local_port; int rec_index = 0; struct mlxsw_sp_sb_cm *cm; int i; memcpy(&cb_ctx, &cb_priv, sizeof(cb_ctx)); masked_count = 0; for (local_port = cb_ctx.local_port_1; local_port < MLXSW_PORT_MAX_PORTS; local_port++) { if (!mlxsw_sp->ports[local_port]) continue; for (i = 0; i < MLXSW_SP_SB_TC_COUNT; i++) { cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, i, MLXSW_REG_SBXX_DIR_INGRESS); mlxsw_reg_sbsr_rec_unpack(sbsr_pl, rec_index++, &cm->occ.cur, &cm->occ.max); } if (++masked_count == cb_ctx.masked_count) break; } masked_count = 0; for (local_port = cb_ctx.local_port_1; local_port < MLXSW_PORT_MAX_PORTS; local_port++) { if (!mlxsw_sp->ports[local_port]) continue; for (i = 0; i < MLXSW_SP_SB_TC_COUNT; i++) { cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, i, MLXSW_REG_SBXX_DIR_EGRESS); mlxsw_reg_sbsr_rec_unpack(sbsr_pl, rec_index++, &cm->occ.cur, &cm->occ.max); } if (++masked_count == cb_ctx.masked_count) break; } }
int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port, unsigned int sb_index, u16 tc_index, enum devlink_sb_pool_type pool_type, u32 *p_cur, u32 *p_max) { struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_core_port_driver_priv(mlxsw_core_port); struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; u8 local_port = mlxsw_sp_port->local_port; u8 pg_buff = tc_index; enum mlxsw_reg_sbxx_dir dir = pool_type; 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); return 0; }
int mlxsw_sp_sb_tc_pool_bind_get(struct mlxsw_core_port *mlxsw_core_port, unsigned int sb_index, u16 tc_index, enum devlink_sb_pool_type pool_type, u16 *p_pool_index, u32 *p_threshold) { struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_core_port_driver_priv(mlxsw_core_port); struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; u8 local_port = mlxsw_sp_port->local_port; u8 pg_buff = tc_index; enum mlxsw_reg_sbxx_dir dir = pool_type; struct mlxsw_sp_sb_cm *cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, pg_buff, dir); *p_threshold = mlxsw_sp_sb_threshold_out(mlxsw_sp, cm->pool, dir, cm->max_buff); *p_pool_index = pool_index_get(cm->pool, pool_type); return 0; }
static int mlxsw_sp_sb_cm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 pg_buff, enum mlxsw_reg_sbxx_dir dir, u32 min_buff, u32 max_buff, u8 pool) { char sbcm_pl[MLXSW_REG_SBCM_LEN]; int err; mlxsw_reg_sbcm_pack(sbcm_pl, local_port, pg_buff, dir, min_buff, max_buff, pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbcm), sbcm_pl); if (err) return err; if (pg_buff < MLXSW_SP_SB_TC_COUNT) { struct mlxsw_sp_sb_cm *cm; cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, pg_buff, dir); cm->min_buff = min_buff; cm->max_buff = max_buff; cm->pool = pool; } return 0; }