diff --git a/userspace/include/fpga_io.h b/userspace/include/fpga_io.h index 8a2a97d4e47e17d65ebda1b34d70f26a78080373..f5f55615c6b4e1ffa53323e555712697683352ce 100644 --- a/userspace/include/fpga_io.h +++ b/userspace/include/fpga_io.h @@ -38,6 +38,9 @@ /* Endpoint */ #define FPGA_BASE_EP0 0x30000 +/* NIC */ +#define FPGA_BASE_NIC 0x20000 + extern volatile uint8_t *_fpga_base_virt; /* libwr/fpga_io.c */ #define FPGA_BASE_ADDR _fpga_base_virt diff --git a/userspace/tools/.gitignore b/userspace/tools/.gitignore index ffdd3807c1363583ee2fea928a2bfeaa36600c2f..b195ea59385fa5dc1454dfafea43e37a063e7b82 100644 --- a/userspace/tools/.gitignore +++ b/userspace/tools/.gitignore @@ -24,3 +24,4 @@ mkpasswd wrs_status_led wrs_sfp_dump wrs_pps_control +wrs_throttling diff --git a/userspace/tools/Makefile b/userspace/tools/Makefile index 1429fe0d2032c0d2a0ebc547904f12cd72b14316..6c0afeec228a252838331dd59fd6f6f9bf8dbad6 100644 --- a/userspace/tools/Makefile +++ b/userspace/tools/Makefile @@ -9,6 +9,7 @@ TOOLS += wrs_checkcfg TOOLS += wrs_status_led TOOLS += mkpasswd TOOLS += wrs_sfp_dump +TOOLS += wrs_throttling PPSI_CONFIG = ../ppsi/include/generated/autoconf.h WR_INSTALL_ROOT ?= /usr/lib/white-rabbit diff --git a/userspace/tools/wrs_throttling.c b/userspace/tools/wrs_throttling.c new file mode 100644 index 0000000000000000000000000000000000000000..230a536917a1571bf7da8757e9da5e48df1008ef --- /dev/null +++ b/userspace/tools/wrs_throttling.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016, CERN + * + * Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdio.h> +#include <getopt.h> +#include <inttypes.h> +#include <stddef.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <libwr/switch_hw.h> +#include <libwr/wrs-msg.h> +#include <fpga_io.h> +#include <regs/nic-regs.h> + +#define nic_write(reg, val) \ + _fpga_writel(FPGA_BASE_NIC + offsetof(struct NIC_WB, reg), val) + +#define nic_read(reg) \ + _fpga_readl(FPGA_BASE_NIC + offsetof(struct NIC_WB, reg)) + +#define MAX_THR 65535 /* b/w thr in HDL is 16-bit value in KB/s */ +#define MIN_THR 2 + +static char *prgname; + +void enable_throttling(int en) +{ + uint32_t val; + + val = nic_read(CR); + if (en) { + val |= NIC_CR_RXTHR_EN; + printf("NIC bandwidth throttling enabled\n"); + } else { + val &= (~NIC_CR_RXTHR_EN); + printf("NIC bandwidth throttling disabled\n"); + } + + nic_write(CR, val); +} + +void print_bw(int print_bps) +{ + uint32_t bw; + + /* first we read the b/w in Bytes/s */ + bw = nic_read(RXBW); + + if (print_bps) + printf("NIC Rx bandwidth: %u B/s\n", bw); + else + printf("NIC Rx bandwidth: %.3f KB/s\n", bw/1024.0); +} + +int set_thr(unsigned thr) +{ + if (thr > MAX_THR || thr < MIN_THR) + return -1; + + printf("Setting NIC Rx bandwidth threshold: %u KB/s\n", thr); + nic_write(MAXRXBW, thr); + + return 0; +} + +void print_settings(void) +{ + uint32_t en; + + en = nic_read(CR) & NIC_CR_RXTHR_EN; + printf("Current settings:\n"); + printf("Throttling: %s\n", en ? "enabled" : "disabled"); + printf("Max bandwidth: %u KB/s\n", nic_read(MAXRXBW)); +} + +void print_help(char *prgname) +{ + printf("wrs_throttling. Commit %s, built on " __DATE__ "\n", + __GIT_VER__); + printf("usage: %s <options>\n", prgname); + printf(" -h Show this help message\n" + " -b Print current b/w in B/s (KB/s by default)\n" + " -l Endless loop mode. Prints the current b/w " + "every 1 s\n" + " -t <KB/s> Set maximum NIC Rx bandwidth to <KB/s>\n" + " -d Disable b/w throttling in NIC\n" + " -s Print current settings of the throttling\n"); +} + +int main(int argc, char *argv[]) +{ + int c = 0; + int print_bps = 0; /* print current b/w in Bytes/s */ + int loop_mode = 0; /* prints current b/w every 1s */ + + prgname = argv[0]; + + + wrs_msg_init(argc, argv); + + if (shw_fpga_mmap_init() < 0) { + pr_error("%s: Can't access device memory\n", prgname); + exit(1); + } + + while ((c = getopt(argc, argv, "hbt:lds")) != -1) { + switch (c) { + case 'b': + /* print current b/w in B/s */ + print_bps = 1; + break; + case 't': + /* set b/w threshold */ + if (set_thr(atoi(optarg)) != -1) { + enable_throttling(1); + } else { + pr_error("Threshold outside allowed range " + "<%d; %d>\n", MIN_THR, MAX_THR); + } + break; + case 'd': + /* disable b/w throttling */ + enable_throttling(0); + break; + case 'l': + loop_mode = 1; + break; + case 's': + print_settings(); + break; + case 'h': + default: + print_help(prgname); + exit(1); + } + } + + /* do actual printing */ + print_bw(print_bps); + while (loop_mode) { + sleep(1); + print_bw(print_bps); + } + + return 0; +}