diff --git a/lib/mqnic/Makefile b/lib/mqnic/Makefile index d53c87477..61102ca17 100644 --- a/lib/mqnic/Makefile +++ b/lib/mqnic/Makefile @@ -22,7 +22,7 @@ all: $(LIB) %.o: %.c $(CC) $(ALL_CFLAGS) -c -o $@ $< -libmqnic.a: mqnic.o mqnic_if.o mqnic_port.o mqnic_sched_block.o mqnic_scheduler.o mqnic_clk_info.o reg_if.o reg_block.o fpga_id.o +libmqnic.a: mqnic.o mqnic_if.o mqnic_port.o mqnic_sched_block.o mqnic_scheduler.o mqnic_clk_info.o mqnic_stats.o reg_if.o reg_block.o fpga_id.o ar rcs $@ $^ install: diff --git a/lib/mqnic/mqnic.c b/lib/mqnic/mqnic.c index 33b5f6ea3..cfcdb2ac7 100644 --- a/lib/mqnic/mqnic.c +++ b/lib/mqnic/mqnic.c @@ -420,6 +420,7 @@ open: dev->app_id = mqnic_reg_read32(rb->regs, MQNIC_RB_APP_INFO_REG_ID); } + mqnic_stats_init(dev); mqnic_clk_info_init(dev); dev->phc_rb = mqnic_find_reg_block(dev->rb_list, MQNIC_RB_PHC_TYPE, MQNIC_RB_PHC_VER, 0); diff --git a/lib/mqnic/mqnic.h b/lib/mqnic/mqnic.h index 042fc9b24..c27166e43 100644 --- a/lib/mqnic/mqnic.h +++ b/lib/mqnic/mqnic.h @@ -151,6 +151,7 @@ struct mqnic { struct mqnic_reg_block *rb_list; struct mqnic_reg_block *fw_id_rb; struct mqnic_reg_block *if_rb; + struct mqnic_reg_block *stats_rb; struct mqnic_reg_block *clk_info_rb; struct mqnic_reg_block *phc_rb; @@ -166,6 +167,11 @@ struct mqnic { uint32_t app_id; + uint32_t stats_offset; + uint32_t stats_count; + uint32_t stats_stride; + uint32_t stats_flags; + uint16_t core_clk_nom_per_ns_num; uint16_t core_clk_nom_per_ns_denom; uint32_t core_clk_nom_freq_hz; @@ -222,4 +228,8 @@ uint32_t mqnic_get_ref_clk_nom_freq_hz(struct mqnic *dev); uint32_t mqnic_get_core_clk_freq_hz(struct mqnic *dev); uint32_t mqnic_get_clk_freq_hz(struct mqnic *dev, int ch); +// mqnic_stats.c +void mqnic_stats_init(struct mqnic *dev); +uint64_t mqnic_stats_read(struct mqnic *dev, int index); + #endif /* MQNIC_H */ diff --git a/lib/mqnic/mqnic_stats.c b/lib/mqnic/mqnic_stats.c new file mode 100644 index 000000000..065dc09aa --- /dev/null +++ b/lib/mqnic/mqnic_stats.c @@ -0,0 +1,60 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include "mqnic.h" + +void mqnic_stats_init(struct mqnic *dev) +{ + dev->stats_rb = mqnic_find_reg_block(dev->rb_list, MQNIC_RB_STATS_TYPE, MQNIC_RB_STATS_VER, 0); + + if (!dev->stats_rb) + return; + + dev->stats_offset = mqnic_reg_read32(dev->stats_rb->regs, MQNIC_RB_STATS_REG_OFFSET); + dev->stats_count = mqnic_reg_read32(dev->stats_rb->regs, MQNIC_RB_STATS_REG_COUNT); + dev->stats_stride = mqnic_reg_read32(dev->stats_rb->regs, MQNIC_RB_STATS_REG_STRIDE); + dev->stats_flags = mqnic_reg_read32(dev->stats_rb->regs, MQNIC_RB_STATS_REG_FLAGS); +} + +uint64_t mqnic_stats_read(struct mqnic *dev, int index) +{ + uint64_t val; + + if (!dev->stats_rb || index < 0 || index >= dev->stats_count) + return 0; + + val = (uint64_t)mqnic_reg_read32(dev->regs, dev->stats_offset + index*8 + 0); + val |= (uint64_t)mqnic_reg_read32(dev->regs, dev->stats_offset + index*8 + 4) << 32; + + return val; +}