int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, unsigned int sb_index) { struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); LIST_HEAD(bulk_list); char *sbsr_pl; unsigned int masked_count; u8 local_port = 0; int i; int err; int err2; sbsr_pl = kmalloc(MLXSW_REG_SBSR_LEN, GFP_KERNEL); if (!sbsr_pl) return -ENOMEM; next_batch: local_port++; masked_count = 0; mlxsw_reg_sbsr_pack(sbsr_pl, true); for (i = 0; i < MLXSW_SP_SB_TC_COUNT; i++) { mlxsw_reg_sbsr_pg_buff_mask_set(sbsr_pl, i, 1); mlxsw_reg_sbsr_tclass_mask_set(sbsr_pl, i, 1); } for (; local_port < MLXSW_PORT_MAX_PORTS; local_port++) { if (!mlxsw_sp->ports[local_port]) continue; 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_POOL_COUNT; i++) { err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i, MLXSW_REG_SBXX_DIR_INGRESS, &bulk_list); if (err) goto out; err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i, MLXSW_REG_SBXX_DIR_EGRESS, &bulk_list); if (err) goto out; } if (++masked_count == MASKED_COUNT_MAX) goto do_query; } do_query: err = mlxsw_reg_trans_query(mlxsw_core, MLXSW_REG(sbsr), sbsr_pl, &bulk_list, NULL, 0); if (err) goto out; if (local_port < MLXSW_PORT_MAX_PORTS) goto next_batch; out: err2 = mlxsw_reg_trans_bulk_wait(&bulk_list); if (!err) err = err2; kfree(sbsr_pl); return err; }
int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, unsigned int sb_index) { struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp_sb_sr_occ_query_cb_ctx cb_ctx; unsigned long cb_priv; LIST_HEAD(bulk_list); char *sbsr_pl; u8 masked_count; u8 local_port_1; u8 local_port = 0; int i; int err; int err2; sbsr_pl = kmalloc(MLXSW_REG_SBSR_LEN, GFP_KERNEL); if (!sbsr_pl) return -ENOMEM; next_batch: local_port++; local_port_1 = local_port; masked_count = 0; mlxsw_reg_sbsr_pack(sbsr_pl, false); for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) mlxsw_reg_sbsr_pg_buff_mask_set(sbsr_pl, i, 1); for (i = 0; i < MLXSW_SP_SB_EG_TC_COUNT; i++) mlxsw_reg_sbsr_tclass_mask_set(sbsr_pl, i, 1); 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); 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, &bulk_list); if (err) goto out; } if (++masked_count == MASKED_COUNT_MAX) goto do_query; } do_query: cb_ctx.masked_count = masked_count; cb_ctx.local_port_1 = local_port_1; memcpy(&cb_priv, &cb_ctx, sizeof(cb_ctx)); err = mlxsw_reg_trans_query(mlxsw_core, MLXSW_REG(sbsr), sbsr_pl, &bulk_list, mlxsw_sp_sb_sr_occ_query_cb, cb_priv); if (err) goto out; if (local_port < mlxsw_core_max_ports(mlxsw_core)) goto next_batch; out: err2 = mlxsw_reg_trans_bulk_wait(&bulk_list); if (!err) err = err2; kfree(sbsr_pl); return err; }