Deleted Added
full compact
cxgbetool.c (252470) cxgbetool.c (253691)
1/*-
2 * Copyright (c) 2011 Chelsio Communications, Inc.
3 * All rights reserved.
4 * Written by: Navdeep Parhar <np@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2011 Chelsio Communications, Inc.
3 * All rights reserved.
4 * Written by: Navdeep Parhar <np@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/tools/tools/cxgbetool/cxgbetool.c 252470 2013-07-01 17:32:07Z np $");
29__FBSDID("$FreeBSD: head/tools/tools/cxgbetool/cxgbetool.c 253691 2013-07-26 22:04:11Z np $");
30
31#include <stdint.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include <ctype.h>
35#include <errno.h>
36#include <err.h>
37#include <fcntl.h>

--- 55 unchanged lines hidden (view full) ---

93 "\ti2c <port> <devaddr> <addr> [<len>] read from i2c device\n"
94 "\tloadfw <fw-image.bin> install firmware\n"
95 "\tmemdump <addr> <len> dump a memory range\n"
96 "\treg <address>[=<val>] read/write register\n"
97 "\treg64 <address>[=<val>] read/write 64 bit register\n"
98 "\tregdump [<module>] ... dump registers\n"
99 "\tstdio interactive mode\n"
100 "\ttcb <tid> read TCB\n"
30
31#include <stdint.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include <ctype.h>
35#include <errno.h>
36#include <err.h>
37#include <fcntl.h>

--- 55 unchanged lines hidden (view full) ---

93 "\ti2c <port> <devaddr> <addr> [<len>] read from i2c device\n"
94 "\tloadfw <fw-image.bin> install firmware\n"
95 "\tmemdump <addr> <len> dump a memory range\n"
96 "\treg <address>[=<val>] read/write register\n"
97 "\treg64 <address>[=<val>] read/write 64 bit register\n"
98 "\tregdump [<module>] ... dump registers\n"
99 "\tstdio interactive mode\n"
100 "\ttcb <tid> read TCB\n"
101 "\ttracer <idx> tx<n>|rx<n> set and enable a tracer)\n"
102 "\ttracer <idx> disable|enable disable or enable a tracer\n"
103 "\ttracer list list all tracers\n"
101 );
102}
103
104static inline unsigned int
105get_card_vers(unsigned int version)
106{
107 return (version & 0x3ff);
108}

--- 1544 unchanged lines hidden (view full) ---

1653 return (EINVAL);
1654 }
1655 port = l;
1656
1657 return doit(CHELSIO_T4_CLEAR_STATS, &port);
1658}
1659
1660static int
104 );
105}
106
107static inline unsigned int
108get_card_vers(unsigned int version)
109{
110 return (version & 0x3ff);
111}

--- 1544 unchanged lines hidden (view full) ---

1656 return (EINVAL);
1657 }
1658 port = l;
1659
1660 return doit(CHELSIO_T4_CLEAR_STATS, &port);
1661}
1662
1663static int
1664show_tracers(void)
1665{
1666 struct t4_tracer t;
1667 char *s;
1668 int rc, port_idx, i;
1669 long long val;
1670
1671 /* Magic values: MPS_TRC_CFG = 0x9800. MPS_TRC_CFG[1:1] = TrcEn */
1672 rc = read_reg(0x9800, 4, &val);
1673 if (rc != 0)
1674 return (rc);
1675 printf("tracing is %s\n", val & 2 ? "ENABLED" : "DISABLED");
1676
1677 t.idx = 0;
1678 for (t.idx = 0; ; t.idx++) {
1679 rc = doit(CHELSIO_T4_GET_TRACER, &t);
1680 if (rc != 0 || t.idx == 0xff)
1681 break;
1682
1683 if (t.tp.port < 4) {
1684 s = "Rx";
1685 port_idx = t.tp.port;
1686 } else if (t.tp.port < 8) {
1687 s = "Tx";
1688 port_idx = t.tp.port - 4;
1689 } else if (t.tp.port < 12) {
1690 s = "loopback";
1691 port_idx = t.tp.port - 8;
1692 } else if (t.tp.port < 16) {
1693 s = "MPS Rx";
1694 port_idx = t.tp.port - 12;
1695 } else if (t.tp.port < 20) {
1696 s = "MPS Tx";
1697 port_idx = t.tp.port - 16;
1698 } else {
1699 s = "unknown";
1700 port_idx = t.tp.port;
1701 }
1702
1703 printf("\ntracer %u (currently %s) captures ", t.idx,
1704 t.enabled ? "ENABLED" : "DISABLED");
1705 if (t.tp.port < 8)
1706 printf("port %u %s, ", port_idx, s);
1707 else
1708 printf("%s %u, ", s, port_idx);
1709 printf("snap length: %u, min length: %u\n", t.tp.snap_len,
1710 t.tp.min_len);
1711 printf("packets captured %smatch filter\n",
1712 t.tp.invert ? "do not " : "");
1713 if (t.tp.skip_ofst) {
1714 printf("filter pattern: ");
1715 for (i = 0; i < t.tp.skip_ofst * 2; i += 2)
1716 printf("%08x%08x", t.tp.data[i],
1717 t.tp.data[i + 1]);
1718 printf("/");
1719 for (i = 0; i < t.tp.skip_ofst * 2; i += 2)
1720 printf("%08x%08x", t.tp.mask[i],
1721 t.tp.mask[i + 1]);
1722 printf("@0\n");
1723 }
1724 printf("filter pattern: ");
1725 for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2)
1726 printf("%08x%08x", t.tp.data[i], t.tp.data[i + 1]);
1727 printf("/");
1728 for (i = t.tp.skip_ofst * 2; i < T4_TRACE_LEN / 4; i += 2)
1729 printf("%08x%08x", t.tp.mask[i], t.tp.mask[i + 1]);
1730 printf("@%u\n", (t.tp.skip_ofst + t.tp.skip_len) * 8);
1731 }
1732
1733 return (rc);
1734}
1735
1736static int
1737tracer_onoff(uint8_t idx, int enabled)
1738{
1739 struct t4_tracer t;
1740
1741 t.idx = idx;
1742 t.enabled = enabled;
1743 t.valid = 0;
1744
1745 return doit(CHELSIO_T4_SET_TRACER, &t);
1746}
1747
1748static void
1749create_tracing_ifnet()
1750{
1751 char *cmd[] = {
1752 "/sbin/ifconfig", __DECONST(char *, nexus), "create", NULL
1753 };
1754 char *env[] = {NULL};
1755
1756 if (vfork() == 0) {
1757 close(STDERR_FILENO);
1758 execve(cmd[0], cmd, env);
1759 _exit(0);
1760 }
1761}
1762
1763/*
1764 * XXX: Allow user to specify snaplen, minlen, and pattern (including inverted
1765 * matching). Right now this is a quick-n-dirty implementation that traces the
1766 * first 128B of all tx or rx on a port
1767 */
1768static int
1769set_tracer(uint8_t idx, int argc, const char *argv[])
1770{
1771 struct t4_tracer t;
1772 int len, port;
1773
1774 bzero(&t, sizeof (t));
1775 t.idx = idx;
1776 t.enabled = 1;
1777 t.valid = 1;
1778
1779 if (argc != 1) {
1780 warnx("must specify tx<n> or rx<n>.");
1781 return (EINVAL);
1782 }
1783
1784 len = strlen(argv[0]);
1785 if (len != 3) {
1786 warnx("argument must be 3 characters (tx<n> or rx<n>)");
1787 return (EINVAL);
1788 }
1789
1790 if (strncmp(argv[0], "tx", 2) == 0) {
1791 port = argv[0][2] - '0';
1792 if (port < 0 || port > 3) {
1793 warnx("'%c' in %s is invalid", argv[0][2], argv[0]);
1794 return (EINVAL);
1795 }
1796 port += 4;
1797 } else if (strncmp(argv[0], "rx", 2) == 0) {
1798 port = argv[0][2] - '0';
1799 if (port < 0 || port > 3) {
1800 warnx("'%c' in %s is invalid", argv[0][2], argv[0]);
1801 return (EINVAL);
1802 }
1803 } else {
1804 warnx("argument '%s' isn't tx<n> or rx<n>", argv[0]);
1805 return (EINVAL);
1806 }
1807
1808 t.tp.snap_len = 128;
1809 t.tp.min_len = 0;
1810 t.tp.skip_ofst = 0;
1811 t.tp.skip_len = 0;
1812 t.tp.invert = 0;
1813 t.tp.port = port;
1814
1815 create_tracing_ifnet();
1816 return doit(CHELSIO_T4_SET_TRACER, &t);
1817}
1818
1819static int
1820tracer_cmd(int argc, const char *argv[])
1821{
1822 long long val;
1823 uint8_t idx;
1824 char *s;
1825
1826 if (argc == 0) {
1827 warnx("tracer: no arguments.");
1828 return (EINVAL);
1829 };
1830
1831 /* list */
1832 if (strcmp(argv[0], "list") == 0) {
1833 if (argc != 1)
1834 warnx("trailing arguments after \"list\" ignored.");
1835
1836 return show_tracers();
1837 }
1838
1839 /* <idx> ... */
1840 s = str_to_number(argv[0], NULL, &val);
1841 if (*s || val > 0xff) {
1842 warnx("\"%s\" is neither an index nor a tracer subcommand.",
1843 argv[0]);
1844 return (EINVAL);
1845 }
1846 idx = (int8_t)val;
1847
1848 /* <idx> disable */
1849 if (argc == 2 && strcmp(argv[1], "disable") == 0)
1850 return tracer_onoff(idx, 0);
1851
1852 /* <idx> enable */
1853 if (argc == 2 && strcmp(argv[1], "enable") == 0)
1854 return tracer_onoff(idx, 1);
1855
1856 /* <idx> ... */
1857 return set_tracer(idx, argc - 1, argv + 1);
1858}
1859
1860static int
1661run_cmd(int argc, const char *argv[])
1662{
1663 int rc = -1;
1664 const char *cmd = argv[0];
1665
1666 /* command */
1667 argc--;
1668 argv++;

--- 13 unchanged lines hidden (view full) ---

1682 else if (!strcmp(cmd, "memdump"))
1683 rc = memdump(argc, argv);
1684 else if (!strcmp(cmd, "tcb"))
1685 rc = read_tcb(argc, argv);
1686 else if (!strcmp(cmd, "i2c"))
1687 rc = read_i2c(argc, argv);
1688 else if (!strcmp(cmd, "clearstats"))
1689 rc = clearstats(argc, argv);
1861run_cmd(int argc, const char *argv[])
1862{
1863 int rc = -1;
1864 const char *cmd = argv[0];
1865
1866 /* command */
1867 argc--;
1868 argv++;

--- 13 unchanged lines hidden (view full) ---

1882 else if (!strcmp(cmd, "memdump"))
1883 rc = memdump(argc, argv);
1884 else if (!strcmp(cmd, "tcb"))
1885 rc = read_tcb(argc, argv);
1886 else if (!strcmp(cmd, "i2c"))
1887 rc = read_i2c(argc, argv);
1888 else if (!strcmp(cmd, "clearstats"))
1889 rc = clearstats(argc, argv);
1890 else if (!strcmp(cmd, "tracer"))
1891 rc = tracer_cmd(argc, argv);
1690 else {
1691 rc = EINVAL;
1692 warnx("invalid command \"%s\"", cmd);
1693 }
1694
1695 return (rc);
1696}
1697

--- 77 unchanged lines hidden ---
1892 else {
1893 rc = EINVAL;
1894 warnx("invalid command \"%s\"", cmd);
1895 }
1896
1897 return (rc);
1898}
1899

--- 77 unchanged lines hidden ---