18275SEric Cheng /* 28275SEric Cheng * CDDL HEADER START 38275SEric Cheng * 48275SEric Cheng * The contents of this file are subject to the terms of the 58275SEric Cheng * Common Development and Distribution License (the "License"). 68275SEric Cheng * You may not use this file except in compliance with the License. 78275SEric Cheng * 88275SEric Cheng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 98275SEric Cheng * or http://www.opensolaris.org/os/licensing. 108275SEric Cheng * See the License for the specific language governing permissions 118275SEric Cheng * and limitations under the License. 128275SEric Cheng * 138275SEric Cheng * When distributing Covered Code, include this CDDL HEADER in each 148275SEric Cheng * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 158275SEric Cheng * If applicable, add the following below this CDDL HEADER, with the 168275SEric Cheng * fields enclosed by brackets "[]" replaced with your own identifying 178275SEric Cheng * information: Portions Copyright [yyyy] [name of copyright owner] 188275SEric Cheng * 198275SEric Cheng * CDDL HEADER END 208275SEric Cheng */ 218275SEric Cheng /* 22*8480SGirish.Moodalbail@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 238275SEric Cheng * Use is subject to license terms. 248275SEric Cheng */ 258275SEric Cheng 268275SEric Cheng #include <sys/mdb_modapi.h> 278275SEric Cheng #include <sys/types.h> 288275SEric Cheng #include <inet/ip.h> 298275SEric Cheng #include <inet/ip6.h> 308275SEric Cheng 318275SEric Cheng #include <sys/mac.h> 328275SEric Cheng #include <sys/mac_provider.h> 338275SEric Cheng #include <sys/mac_client.h> 348275SEric Cheng #include <sys/mac_client_impl.h> 358275SEric Cheng #include <sys/mac_flow_impl.h> 368275SEric Cheng #include <sys/mac_soft_ring.h> 378275SEric Cheng 388275SEric Cheng #define STRSIZE 64 398275SEric Cheng #define MAC_RX_SRS_SIZE (MAX_RINGS_PER_GROUP * sizeof (uintptr_t)) 408275SEric Cheng 418275SEric Cheng #define LAYERED_WALKER_FOR_FLOW "flow_entry_cache" 428275SEric Cheng #define LAYERED_WALKER_FOR_SRS "mac_srs_cache" 438275SEric Cheng #define LAYERED_WALKER_FOR_RING "mac_ring_cache" 448275SEric Cheng 458275SEric Cheng /* arguments passed to mac_flow dee-command */ 468275SEric Cheng #define MAC_FLOW_NONE 0x01 478275SEric Cheng #define MAC_FLOW_ATTR 0x02 488275SEric Cheng #define MAC_FLOW_PROP 0x04 498275SEric Cheng #define MAC_FLOW_RX 0x08 508275SEric Cheng #define MAC_FLOW_TX 0x10 518275SEric Cheng #define MAC_FLOW_USER 0x20 528275SEric Cheng #define MAC_FLOW_STATS 0x40 538275SEric Cheng #define MAC_FLOW_MISC 0x80 548275SEric Cheng 558275SEric Cheng /* arguments passed to mac_srs dee-command */ 56*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_NONE 0x00 57*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RX 0x01 58*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TX 0x02 59*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_STAT 0x04 60*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_CPU 0x08 61*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_VERBOSE 0x10 62*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RXSTAT (MAC_SRS_RX|MAC_SRS_STAT) 63*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TXSTAT (MAC_SRS_TX|MAC_SRS_STAT) 64*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RXCPU (MAC_SRS_RX|MAC_SRS_CPU) 65*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TXCPU (MAC_SRS_TX|MAC_SRS_CPU) 66*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RXCPUVERBOSE (MAC_SRS_RXCPU|MAC_SRS_VERBOSE) 67*8480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TXCPUVERBOSE (MAC_SRS_TXCPU|MAC_SRS_VERBOSE) 688275SEric Cheng 698275SEric Cheng static char * 708275SEric Cheng mac_flow_proto2str(uint8_t protocol) 718275SEric Cheng { 728275SEric Cheng switch (protocol) { 738275SEric Cheng case IPPROTO_TCP: 748275SEric Cheng return ("tcp"); 758275SEric Cheng case IPPROTO_UDP: 768275SEric Cheng return ("udp"); 778275SEric Cheng case IPPROTO_SCTP: 788275SEric Cheng return ("sctp"); 798275SEric Cheng case IPPROTO_ICMP: 808275SEric Cheng return ("icmp"); 818275SEric Cheng case IPPROTO_ICMPV6: 828275SEric Cheng return ("icmpv6"); 838275SEric Cheng default: 848275SEric Cheng return ("--"); 858275SEric Cheng } 868275SEric Cheng } 878275SEric Cheng 888275SEric Cheng static char * 898275SEric Cheng mac_flow_priority2str(mac_priority_level_t prio) 908275SEric Cheng { 918275SEric Cheng switch (prio) { 928275SEric Cheng case MPL_LOW: 938275SEric Cheng return ("low"); 948275SEric Cheng case MPL_MEDIUM: 958275SEric Cheng return ("medium"); 968275SEric Cheng case MPL_HIGH: 978275SEric Cheng return ("high"); 988275SEric Cheng case MPL_RESET: 998275SEric Cheng return ("reset"); 1008275SEric Cheng default: 1018275SEric Cheng return ("--"); 1028275SEric Cheng } 1038275SEric Cheng } 1048275SEric Cheng 1058275SEric Cheng /* 1068275SEric Cheng * Convert bandwidth in bps to a string in mpbs. 1078275SEric Cheng */ 1088275SEric Cheng static char * 1098275SEric Cheng mac_flow_bw2str(uint64_t bw, char *buf, ssize_t len) 1108275SEric Cheng { 1118275SEric Cheng int kbps, mbps; 1128275SEric Cheng 1138275SEric Cheng kbps = (bw % 1000000)/1000; 1148275SEric Cheng mbps = bw/1000000; 1158275SEric Cheng if ((mbps == 0) && (kbps != 0)) 1168275SEric Cheng mdb_snprintf(buf, len, "0.%03u", kbps); 1178275SEric Cheng else 1188275SEric Cheng mdb_snprintf(buf, len, "%5u", mbps); 1198275SEric Cheng return (buf); 1208275SEric Cheng } 1218275SEric Cheng 1228275SEric Cheng static void 1238275SEric Cheng mac_flow_print_header(uint_t args) 1248275SEric Cheng { 1258275SEric Cheng switch (args) { 1268275SEric Cheng case MAC_FLOW_NONE: 1278275SEric Cheng mdb_printf("%<u>%?s %-32s %-6s %?s %?s %-20s%</u>\n", 1288275SEric Cheng "ADDR", "FLOW NAME", "LINKID", "MCIP", "MIP", 1298275SEric Cheng "MIP NAME"); 1308275SEric Cheng break; 1318275SEric Cheng case MAC_FLOW_ATTR: 1328275SEric Cheng mdb_printf("%<u>%?s %-32s %-7s %6s " 1338275SEric Cheng "%-9s %s%</u>\n", 1348275SEric Cheng "ADDR", "FLOW NAME", "PROTO", "PORT", 1358275SEric Cheng "DSFLD:MSK", "IPADDR"); 1368275SEric Cheng break; 1378275SEric Cheng case MAC_FLOW_PROP: 1388275SEric Cheng mdb_printf("%<u>%?s %-32s %8s %9s%</u>\n", 1398275SEric Cheng "ADDR", "FLOW NAME", "MAXBW(M)", "PRIORITY"); 1408275SEric Cheng break; 1418275SEric Cheng case MAC_FLOW_MISC: 1428275SEric Cheng mdb_printf("%<u>%?s %-32s %10s %10s " 1438275SEric Cheng "%32s %s%</u>\n", 1448275SEric Cheng "ADDR", "FLOW NAME", "TYPE", "FLAGS", 1458275SEric Cheng "MATCH_FN", "ZONE"); 1468275SEric Cheng break; 1478275SEric Cheng case MAC_FLOW_RX: 148*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-24s %7s %s%</u>\n", 149*8480SGirish.Moodalbail@Sun.COM "ADDR", "FLOW NAME", "SRS_CNT", "RX_SRS"); 1508275SEric Cheng break; 1518275SEric Cheng case MAC_FLOW_TX: 1528275SEric Cheng mdb_printf("%<u>%?s %-32s %?s %</u>\n", 1538275SEric Cheng "ADDR", "FLOW NAME", "TX_SRS"); 1548275SEric Cheng break; 1558275SEric Cheng case MAC_FLOW_STATS: 1568275SEric Cheng mdb_printf("%<u>%?s %-32s %?s %?s%</u>\n", 1578275SEric Cheng "ADDR", "FLOW NAME", "RBYTES", "OBYTES"); 1588275SEric Cheng break; 1598275SEric Cheng } 1608275SEric Cheng } 1618275SEric Cheng 1628275SEric Cheng /* 1638275SEric Cheng * Display selected fields of the flow_entry_t structure 1648275SEric Cheng */ 1658275SEric Cheng static int 1668275SEric Cheng mac_flow_dcmd_output(uintptr_t addr, uint_t flags, uint_t args) 1678275SEric Cheng { 1688275SEric Cheng static const mdb_bitmask_t flow_type_bits[] = { 1698275SEric Cheng {"P", FLOW_PRIMARY_MAC, FLOW_PRIMARY_MAC}, 1708275SEric Cheng {"V", FLOW_VNIC_MAC, FLOW_VNIC_MAC}, 1718275SEric Cheng {"M", FLOW_MCAST, FLOW_MCAST}, 1728275SEric Cheng {"O", FLOW_OTHER, FLOW_OTHER}, 1738275SEric Cheng {"U", FLOW_USER, FLOW_USER}, 1748275SEric Cheng {"V", FLOW_VNIC, FLOW_VNIC}, 1758275SEric Cheng {"NS", FLOW_NO_STATS, FLOW_NO_STATS}, 1768275SEric Cheng { NULL, 0, 0 } 1778275SEric Cheng }; 1788275SEric Cheng #define FLOW_MAX_TYPE (sizeof (flow_type_bits) / sizeof (mdb_bitmask_t)) 1798275SEric Cheng 1808275SEric Cheng static const mdb_bitmask_t flow_flag_bits[] = { 1818275SEric Cheng {"Q", FE_QUIESCE, FE_QUIESCE}, 1828275SEric Cheng {"W", FE_WAITER, FE_WAITER}, 1838275SEric Cheng {"T", FE_FLOW_TAB, FE_FLOW_TAB}, 1848275SEric Cheng {"G", FE_G_FLOW_HASH, FE_G_FLOW_HASH}, 1858275SEric Cheng {"I", FE_INCIPIENT, FE_INCIPIENT}, 1868275SEric Cheng {"C", FE_CONDEMNED, FE_CONDEMNED}, 1878275SEric Cheng {"NU", FE_UF_NO_DATAPATH, FE_UF_NO_DATAPATH}, 1888275SEric Cheng {"NC", FE_MC_NO_DATAPATH, FE_MC_NO_DATAPATH}, 1898275SEric Cheng { NULL, 0, 0 } 1908275SEric Cheng }; 1918275SEric Cheng #define FLOW_MAX_FLAGS (sizeof (flow_flag_bits) / sizeof (mdb_bitmask_t)) 1928275SEric Cheng flow_entry_t fe; 1938275SEric Cheng mac_client_impl_t mcip; 1948275SEric Cheng mac_impl_t mip; 1958275SEric Cheng 1968275SEric Cheng if (mdb_vread(&fe, sizeof (fe), addr) == -1) { 1978275SEric Cheng mdb_warn("failed to read struct flow_entry_s at %p", addr); 1988275SEric Cheng return (DCMD_ERR); 1998275SEric Cheng } 2008275SEric Cheng if (args & MAC_FLOW_USER) { 2018275SEric Cheng args &= ~MAC_FLOW_USER; 2028275SEric Cheng if (fe.fe_type & FLOW_MCAST) { 2038275SEric Cheng if (DCMD_HDRSPEC(flags)) 2048275SEric Cheng mac_flow_print_header(args); 2058275SEric Cheng return (DCMD_OK); 2068275SEric Cheng } 2078275SEric Cheng } 2088275SEric Cheng if (DCMD_HDRSPEC(flags)) 2098275SEric Cheng mac_flow_print_header(args); 2108275SEric Cheng bzero(&mcip, sizeof (mcip)); 2118275SEric Cheng bzero(&mip, sizeof (mip)); 2128275SEric Cheng if (fe.fe_mcip != NULL && mdb_vread(&mcip, sizeof (mcip), 2138275SEric Cheng (uintptr_t)fe.fe_mcip) == sizeof (mcip)) { 2148275SEric Cheng (void) mdb_vread(&mip, sizeof (mip), (uintptr_t)mcip.mci_mip); 2158275SEric Cheng } 2168275SEric Cheng switch (args) { 2178275SEric Cheng case MAC_FLOW_NONE: { 2188275SEric Cheng mdb_printf("%?p %-32s %6d %?p " 2198275SEric Cheng "%?p %-20s\n", 2208275SEric Cheng addr, fe.fe_flow_name, fe.fe_link_id, fe.fe_mcip, 2218275SEric Cheng mcip.mci_mip, mip.mi_name); 2228275SEric Cheng break; 2238275SEric Cheng } 2248275SEric Cheng case MAC_FLOW_ATTR: { 2258275SEric Cheng struct in_addr in4; 2268275SEric Cheng uintptr_t desc_addr; 2278275SEric Cheng flow_desc_t fdesc; 2288275SEric Cheng 2298275SEric Cheng desc_addr = addr + OFFSETOF(flow_entry_t, fe_flow_desc); 2308275SEric Cheng if (mdb_vread(&fdesc, sizeof (fdesc), desc_addr) == -1) { 2318275SEric Cheng mdb_warn("failed to read struct flow_description at %p", 2328275SEric Cheng desc_addr); 2338275SEric Cheng return (DCMD_ERR); 2348275SEric Cheng } 2358275SEric Cheng mdb_printf("%?p %-32s " 2368275SEric Cheng "%-7s %6d" 2378275SEric Cheng "%4d:%-4d ", 2388275SEric Cheng addr, fe.fe_flow_name, 2398275SEric Cheng mac_flow_proto2str(fdesc.fd_protocol), fdesc.fd_local_port, 2408275SEric Cheng fdesc.fd_dsfield, fdesc.fd_dsfield_mask); 2418275SEric Cheng if (fdesc.fd_ipversion == IPV4_VERSION) { 2428275SEric Cheng IN6_V4MAPPED_TO_INADDR(&fdesc.fd_local_addr, &in4); 2438275SEric Cheng mdb_printf("%I", in4.s_addr); 2448275SEric Cheng } else if (fdesc.fd_ipversion == IPV6_VERSION) { 2458275SEric Cheng mdb_printf("%N", &fdesc.fd_local_addr); 2468275SEric Cheng } else { 2478275SEric Cheng mdb_printf("%s", "--"); 2488275SEric Cheng } 2498275SEric Cheng mdb_printf("\n"); 2508275SEric Cheng break; 2518275SEric Cheng } 2528275SEric Cheng case MAC_FLOW_PROP: { 2538275SEric Cheng uintptr_t prop_addr; 2548275SEric Cheng char bwstr[STRSIZE]; 2558275SEric Cheng mac_resource_props_t fprop; 2568275SEric Cheng 2578275SEric Cheng prop_addr = addr + OFFSETOF(flow_entry_t, fe_resource_props); 2588275SEric Cheng if (mdb_vread(&fprop, sizeof (fprop), prop_addr) == -1) { 2598275SEric Cheng mdb_warn("failed to read struct mac_resoource_props " 2608275SEric Cheng "at %p", prop_addr); 2618275SEric Cheng return (DCMD_ERR); 2628275SEric Cheng } 2638275SEric Cheng mdb_printf("%?p %-32s " 2648275SEric Cheng "%8s %9s\n", 2658275SEric Cheng addr, fe.fe_flow_name, 2668275SEric Cheng mac_flow_bw2str(fprop.mrp_maxbw, bwstr, STRSIZE), 2678275SEric Cheng mac_flow_priority2str(fprop.mrp_priority)); 2688275SEric Cheng break; 2698275SEric Cheng } 2708275SEric Cheng case MAC_FLOW_MISC: { 2718275SEric Cheng char flow_flags[2 * FLOW_MAX_FLAGS]; 2728275SEric Cheng char flow_type[2 * FLOW_MAX_TYPE]; 2738275SEric Cheng GElf_Sym sym; 2748275SEric Cheng char func_name[MDB_SYM_NAMLEN] = ""; 2758275SEric Cheng uintptr_t func, match_addr; 2768275SEric Cheng 2778275SEric Cheng match_addr = addr + OFFSETOF(flow_entry_t, fe_match); 2788275SEric Cheng (void) mdb_vread(&func, sizeof (func), match_addr); 2798275SEric Cheng (void) mdb_lookup_by_addr(func, MDB_SYM_EXACT, func_name, 2808275SEric Cheng MDB_SYM_NAMLEN, &sym); 2818275SEric Cheng mdb_snprintf(flow_flags, 2 * FLOW_MAX_FLAGS, "%hb", 2828275SEric Cheng fe.fe_flags, flow_flag_bits); 2838275SEric Cheng mdb_snprintf(flow_type, 2 * FLOW_MAX_TYPE, "%hb", 2848275SEric Cheng fe.fe_type, flow_type_bits); 2858275SEric Cheng mdb_printf("%?p %-32s %10s %10s " 2868275SEric Cheng "%32s %-d\n", 2878275SEric Cheng addr, fe.fe_flow_name, flow_type, flow_flags, 2888275SEric Cheng func_name, fe.fe_zoneid); 2898275SEric Cheng break; 2908275SEric Cheng } 2918275SEric Cheng case MAC_FLOW_RX: { 292*8480SGirish.Moodalbail@Sun.COM uintptr_t rxaddr, rx_srs[MAX_RINGS_PER_GROUP] = {0}; 2938275SEric Cheng int i; 2948275SEric Cheng 2958275SEric Cheng rxaddr = addr + OFFSETOF(flow_entry_t, fe_rx_srs); 2968275SEric Cheng (void) mdb_vread(rx_srs, MAC_RX_SRS_SIZE, rxaddr); 297*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-24s %7d ", 298*8480SGirish.Moodalbail@Sun.COM addr, fe.fe_flow_name, fe.fe_rx_srs_cnt); 2998275SEric Cheng for (i = 0; i < MAX_RINGS_PER_GROUP; i++) { 3008275SEric Cheng if (rx_srs[i] == 0) 3018275SEric Cheng continue; 3028275SEric Cheng mdb_printf("%p ", rx_srs[i]); 3038275SEric Cheng } 3048275SEric Cheng mdb_printf("\n"); 3058275SEric Cheng break; 3068275SEric Cheng } 3078275SEric Cheng case MAC_FLOW_TX: { 3088275SEric Cheng uintptr_t tx_srs = 0, txaddr; 3098275SEric Cheng 3108275SEric Cheng txaddr = addr + OFFSETOF(flow_entry_t, fe_tx_srs); 3118275SEric Cheng (void) mdb_vread(&tx_srs, sizeof (uintptr_t), txaddr); 3128275SEric Cheng mdb_printf("%?p %-32s %?p\n", 3138275SEric Cheng addr, fe.fe_flow_name, fe.fe_tx_srs); 3148275SEric Cheng break; 3158275SEric Cheng } 3168275SEric Cheng case MAC_FLOW_STATS: { 3178275SEric Cheng mdb_printf("%?p %-32s %16llu %16llu\n", 3188275SEric Cheng addr, fe.fe_flow_name, fe.fe_flowstats.fs_rbytes, 3198275SEric Cheng fe.fe_flowstats.fs_obytes); 3208275SEric Cheng break; 3218275SEric Cheng } 3228275SEric Cheng } 3238275SEric Cheng return (DCMD_OK); 3248275SEric Cheng } 3258275SEric Cheng 3268275SEric Cheng /* 3278275SEric Cheng * Parse the arguments passed to the dcmd and print all or one flow_entry_t 3288275SEric Cheng * structures 3298275SEric Cheng */ 3308275SEric Cheng static int 3318275SEric Cheng mac_flow_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 3328275SEric Cheng { 3338275SEric Cheng uint_t args = 0; 3348275SEric Cheng 3358275SEric Cheng if (!(flags & DCMD_ADDRSPEC)) { 3368275SEric Cheng if (mdb_walk_dcmd("mac_flow", "mac_flow", argc, argv) == -1) { 3378275SEric Cheng mdb_warn("failed to walk 'mac_flow'"); 3388275SEric Cheng return (DCMD_ERR); 3398275SEric Cheng } 3408275SEric Cheng return (DCMD_OK); 3418275SEric Cheng } 3428275SEric Cheng if ((mdb_getopts(argc, argv, 3438275SEric Cheng 'a', MDB_OPT_SETBITS, MAC_FLOW_ATTR, &args, 3448275SEric Cheng 'p', MDB_OPT_SETBITS, MAC_FLOW_PROP, &args, 3458275SEric Cheng 'm', MDB_OPT_SETBITS, MAC_FLOW_MISC, &args, 3468275SEric Cheng 'r', MDB_OPT_SETBITS, MAC_FLOW_RX, &args, 3478275SEric Cheng 't', MDB_OPT_SETBITS, MAC_FLOW_TX, &args, 3488275SEric Cheng 's', MDB_OPT_SETBITS, MAC_FLOW_STATS, &args, 3498275SEric Cheng 'u', MDB_OPT_SETBITS, MAC_FLOW_USER, &args) != argc)) { 3508275SEric Cheng return (DCMD_USAGE); 3518275SEric Cheng } 3528275SEric Cheng if (argc > 2 || (argc == 2 && !(args & MAC_FLOW_USER))) 3538275SEric Cheng return (DCMD_USAGE); 3548275SEric Cheng /* 3558275SEric Cheng * If no arguments was specified or just "-u" was specified then 3568275SEric Cheng * we default to printing basic information of flows. 3578275SEric Cheng */ 3588275SEric Cheng if (args == 0 || args == MAC_FLOW_USER) 3598275SEric Cheng args |= MAC_FLOW_NONE; 3608275SEric Cheng 3618275SEric Cheng return (mac_flow_dcmd_output(addr, flags, args)); 3628275SEric Cheng } 3638275SEric Cheng 3648275SEric Cheng static void 3658275SEric Cheng mac_flow_help(void) 3668275SEric Cheng { 3678275SEric Cheng mdb_printf("If an address is specified, then flow_entry structure at " 3688275SEric Cheng "that address is printed. Otherwise all the flows in the system " 3698275SEric Cheng "are printed.\n"); 3708275SEric Cheng mdb_printf("Options:\n" 3718275SEric Cheng "\t-u\tdisplay user defined link & vnic flows.\n" 3728275SEric Cheng "\t-a\tdisplay flow attributes\n" 3738275SEric Cheng "\t-p\tdisplay flow properties\n" 3748275SEric Cheng "\t-r\tdisplay rx side information\n" 3758275SEric Cheng "\t-t\tdisplay tx side information\n" 3768275SEric Cheng "\t-s\tdisplay flow statistics\n" 3778275SEric Cheng "\t-m\tdisplay miscellaneous flow information\n\n"); 3788275SEric Cheng mdb_printf("%<u>Interpreting Flow type and Flow flags output.%</u>\n"); 3798275SEric Cheng mdb_printf("Flow Types:\n"); 3808275SEric Cheng mdb_printf("\t P --> FLOW_PRIMARY_MAC\n"); 3818275SEric Cheng mdb_printf("\t V --> FLOW_VNIC_MAC\n"); 3828275SEric Cheng mdb_printf("\t M --> FLOW_MCAST\n"); 3838275SEric Cheng mdb_printf("\t O --> FLOW_OTHER\n"); 3848275SEric Cheng mdb_printf("\t U --> FLOW_USER\n"); 3858275SEric Cheng mdb_printf("\t NS --> FLOW_NO_STATS\n\n"); 3868275SEric Cheng mdb_printf("Flow Flags:\n"); 3878275SEric Cheng mdb_printf("\t Q --> FE_QUIESCE\n"); 3888275SEric Cheng mdb_printf("\t W --> FE_WAITER\n"); 3898275SEric Cheng mdb_printf("\t T --> FE_FLOW_TAB\n"); 3908275SEric Cheng mdb_printf("\t G --> FE_G_FLOW_HASH\n"); 3918275SEric Cheng mdb_printf("\t I --> FE_INCIPIENT\n"); 3928275SEric Cheng mdb_printf("\t C --> FE_CONDEMNED\n"); 3938275SEric Cheng mdb_printf("\t NU --> FE_UF_NO_DATAPATH\n"); 3948275SEric Cheng mdb_printf("\t NC --> FE_MC_NO_DATAPATH\n"); 3958275SEric Cheng } 3968275SEric Cheng 3978275SEric Cheng /* 3988275SEric Cheng * called once by the debugger when the mac_flow walk begins. 3998275SEric Cheng */ 4008275SEric Cheng static int 4018275SEric Cheng mac_flow_walk_init(mdb_walk_state_t *wsp) 4028275SEric Cheng { 4038275SEric Cheng if (mdb_layered_walk(LAYERED_WALKER_FOR_FLOW, wsp) == -1) { 4048275SEric Cheng mdb_warn("failed to walk 'mac_flow'"); 4058275SEric Cheng return (WALK_ERR); 4068275SEric Cheng } 4078275SEric Cheng return (WALK_NEXT); 4088275SEric Cheng } 4098275SEric Cheng 4108275SEric Cheng /* 4118275SEric Cheng * Common walker step funciton for flow_entry_t, mac_soft_ring_set_t and 4128275SEric Cheng * mac_ring_t. 4138275SEric Cheng * 4148275SEric Cheng * Steps through each flow_entry_t and calls the callback function. If the 4158275SEric Cheng * user executed ::walk mac_flow, it just prints the address or if the user 4168275SEric Cheng * executed ::mac_flow it displays selected fields of flow_entry_t structure 4178275SEric Cheng * by calling "mac_flow_dcmd" 4188275SEric Cheng */ 4198275SEric Cheng static int 4208275SEric Cheng mac_common_walk_step(mdb_walk_state_t *wsp) 4218275SEric Cheng { 4228275SEric Cheng int status; 4238275SEric Cheng 4248275SEric Cheng if (wsp->walk_addr == NULL) 4258275SEric Cheng return (WALK_DONE); 4268275SEric Cheng 4278275SEric Cheng status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 4288275SEric Cheng wsp->walk_cbdata); 4298275SEric Cheng 4308275SEric Cheng return (status); 4318275SEric Cheng } 4328275SEric Cheng 4338275SEric Cheng static char * 4348275SEric Cheng mac_srs_txmode2str(mac_tx_srs_mode_t mode) 4358275SEric Cheng { 4368275SEric Cheng switch (mode) { 4378275SEric Cheng case SRS_TX_DEFAULT: 438*8480SGirish.Moodalbail@Sun.COM return ("DEF"); 4398275SEric Cheng case SRS_TX_SERIALIZE: 440*8480SGirish.Moodalbail@Sun.COM return ("SER"); 4418275SEric Cheng case SRS_TX_FANOUT: 442*8480SGirish.Moodalbail@Sun.COM return ("FO"); 4438275SEric Cheng case SRS_TX_BW: 444*8480SGirish.Moodalbail@Sun.COM return ("BW"); 4458275SEric Cheng case SRS_TX_BW_FANOUT: 446*8480SGirish.Moodalbail@Sun.COM return ("BWFO"); 4478275SEric Cheng } 4488275SEric Cheng return ("--"); 4498275SEric Cheng } 4508275SEric Cheng 4518275SEric Cheng static void 4528275SEric Cheng mac_srs_help(void) 4538275SEric Cheng { 4548275SEric Cheng mdb_printf("If an address is specified, then mac_soft_ring_set " 4558275SEric Cheng "structure at that address is printed. Otherwise all the " 4568275SEric Cheng "SRS in the system are printed.\n"); 4578275SEric Cheng mdb_printf("Options:\n" 4588275SEric Cheng "\t-r\tdisplay recieve side SRS structures\n" 459*8480SGirish.Moodalbail@Sun.COM "\t-t\tdisplay transmit side SRS structures\n" 460*8480SGirish.Moodalbail@Sun.COM "\t-s\tdisplay statistics for RX or TX side\n" 461*8480SGirish.Moodalbail@Sun.COM "\t-c\tdisplay CPU binding for RX or TX side\n" 462*8480SGirish.Moodalbail@Sun.COM "\t-v\tverbose flag for CPU binding to list cpus\n" 463*8480SGirish.Moodalbail@Sun.COM "Note: use -r or -t (to specify RX or TX side respectively) along " 464*8480SGirish.Moodalbail@Sun.COM "with -c or -s\n"); 465*8480SGirish.Moodalbail@Sun.COM mdb_printf("\n%<u>Interpreting TX Modes%</u>\n"); 466*8480SGirish.Moodalbail@Sun.COM mdb_printf("\t DEF --> Default\n"); 467*8480SGirish.Moodalbail@Sun.COM mdb_printf("\t SER --> Serialize\n"); 468*8480SGirish.Moodalbail@Sun.COM mdb_printf("\t FO --> Fanout\n"); 469*8480SGirish.Moodalbail@Sun.COM mdb_printf("\t BW --> Bandwidth\n"); 470*8480SGirish.Moodalbail@Sun.COM mdb_printf("\tBWFO --> Bandwidth Fanout\n"); 471*8480SGirish.Moodalbail@Sun.COM } 472*8480SGirish.Moodalbail@Sun.COM 473*8480SGirish.Moodalbail@Sun.COM /* 474*8480SGirish.Moodalbail@Sun.COM * In verbose mode "::mac_srs -rcv or ::mac_srs -tcv", we print the CPUs 475*8480SGirish.Moodalbail@Sun.COM * assigned to a link and CPUS assigned to the soft rings. 476*8480SGirish.Moodalbail@Sun.COM * 'len' is used for formatting the output and represents the number of 477*8480SGirish.Moodalbail@Sun.COM * spaces between CPU list and Fanout CPU list in the output. 478*8480SGirish.Moodalbail@Sun.COM */ 479*8480SGirish.Moodalbail@Sun.COM static boolean_t 480*8480SGirish.Moodalbail@Sun.COM mac_srs_print_cpu(int *i, uint32_t cnt, uint32_t *cpu_list, int *len) 481*8480SGirish.Moodalbail@Sun.COM { 482*8480SGirish.Moodalbail@Sun.COM int num = 0; 483*8480SGirish.Moodalbail@Sun.COM 484*8480SGirish.Moodalbail@Sun.COM if (*i == 0) 485*8480SGirish.Moodalbail@Sun.COM mdb_printf("("); 486*8480SGirish.Moodalbail@Sun.COM else 487*8480SGirish.Moodalbail@Sun.COM mdb_printf(" "); 488*8480SGirish.Moodalbail@Sun.COM while (*i < cnt) { 489*8480SGirish.Moodalbail@Sun.COM /* We print 6 CPU's at a time to keep display within 80 cols */ 490*8480SGirish.Moodalbail@Sun.COM if (((num + 1) % 7) == 0) { 491*8480SGirish.Moodalbail@Sun.COM if (len != NULL) 492*8480SGirish.Moodalbail@Sun.COM *len = 2; 493*8480SGirish.Moodalbail@Sun.COM return (B_FALSE); 494*8480SGirish.Moodalbail@Sun.COM } 495*8480SGirish.Moodalbail@Sun.COM mdb_printf("%02x%c", cpu_list[*i], ((*i == cnt - 1)?')':',')); 496*8480SGirish.Moodalbail@Sun.COM ++*i; 497*8480SGirish.Moodalbail@Sun.COM ++num; 498*8480SGirish.Moodalbail@Sun.COM } 499*8480SGirish.Moodalbail@Sun.COM if (len != NULL) 500*8480SGirish.Moodalbail@Sun.COM *len = (7 - num) * 3; 501*8480SGirish.Moodalbail@Sun.COM return (B_TRUE); 5028275SEric Cheng } 5038275SEric Cheng 5048275SEric Cheng static int 5058275SEric Cheng mac_srs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5068275SEric Cheng { 507*8480SGirish.Moodalbail@Sun.COM uint_t args = MAC_SRS_NONE; 5088275SEric Cheng mac_soft_ring_set_t srs; 509*8480SGirish.Moodalbail@Sun.COM mac_client_impl_t mci; 5108275SEric Cheng 5118275SEric Cheng if (!(flags & DCMD_ADDRSPEC)) { 5128275SEric Cheng if (mdb_walk_dcmd("mac_srs", "mac_srs", argc, argv) == -1) { 5138275SEric Cheng mdb_warn("failed to walk 'mac_srs'"); 5148275SEric Cheng return (DCMD_ERR); 5158275SEric Cheng } 5168275SEric Cheng return (DCMD_OK); 5178275SEric Cheng } 518*8480SGirish.Moodalbail@Sun.COM if (mdb_getopts(argc, argv, 5198275SEric Cheng 'r', MDB_OPT_SETBITS, MAC_SRS_RX, &args, 520*8480SGirish.Moodalbail@Sun.COM 't', MDB_OPT_SETBITS, MAC_SRS_TX, &args, 521*8480SGirish.Moodalbail@Sun.COM 'c', MDB_OPT_SETBITS, MAC_SRS_CPU, &args, 522*8480SGirish.Moodalbail@Sun.COM 'v', MDB_OPT_SETBITS, MAC_SRS_VERBOSE, &args, 523*8480SGirish.Moodalbail@Sun.COM 's', MDB_OPT_SETBITS, MAC_SRS_STAT, &args) != argc) { 5248275SEric Cheng return (DCMD_USAGE); 5258275SEric Cheng } 526*8480SGirish.Moodalbail@Sun.COM 527*8480SGirish.Moodalbail@Sun.COM if (argc > 2) 5288275SEric Cheng return (DCMD_USAGE); 5298275SEric Cheng 5308275SEric Cheng if (mdb_vread(&srs, sizeof (srs), addr) == -1) { 5318275SEric Cheng mdb_warn("failed to read struct mac_soft_ring_set_s at %p", 5328275SEric Cheng addr); 5338275SEric Cheng return (DCMD_ERR); 5348275SEric Cheng } 535*8480SGirish.Moodalbail@Sun.COM if (mdb_vread(&mci, sizeof (mci), (uintptr_t)srs.srs_mcip) == -1) { 536*8480SGirish.Moodalbail@Sun.COM mdb_warn("failed to read struct mac_client_impl_t at %p " 537*8480SGirish.Moodalbail@Sun.COM "for SRS %p", srs.srs_mcip, addr); 538*8480SGirish.Moodalbail@Sun.COM return (DCMD_ERR); 539*8480SGirish.Moodalbail@Sun.COM } 5408275SEric Cheng 5418275SEric Cheng switch (args) { 5428275SEric Cheng case MAC_SRS_RX: { 5438275SEric Cheng if (DCMD_HDRSPEC(flags)) { 544*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-8s %-8s %-8s " 545*8480SGirish.Moodalbail@Sun.COM "%-8s %-3s\n", 546*8480SGirish.Moodalbail@Sun.COM "", "", "", "", "MBLK", 547*8480SGirish.Moodalbail@Sun.COM "Q", "SR"); 548*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %-8s %-8s %-8s " 549*8480SGirish.Moodalbail@Sun.COM "%-8s %-3s%</u>\n", 550*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "STATE", "TYPE", "CNT", 551*8480SGirish.Moodalbail@Sun.COM "BYTES", "CNT"); 5528275SEric Cheng } 5538275SEric Cheng if (srs.srs_type & SRST_TX) 5548275SEric Cheng return (DCMD_OK); 555*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %08x %08x " 556*8480SGirish.Moodalbail@Sun.COM "%-8d %-8d %-3d\n", 557*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, srs.srs_state, srs.srs_type, 558*8480SGirish.Moodalbail@Sun.COM srs.srs_count, srs.srs_size, srs.srs_soft_ring_count); 5598275SEric Cheng break; 5608275SEric Cheng } 5618275SEric Cheng case MAC_SRS_TX: { 5628275SEric Cheng if (DCMD_HDRSPEC(flags)) { 563*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-16s %-4s %-8s " 564*8480SGirish.Moodalbail@Sun.COM "%-8s %-8s %-8s %-3s\n", 565*8480SGirish.Moodalbail@Sun.COM "", "", "TX", "", 566*8480SGirish.Moodalbail@Sun.COM "", "MBLK", "Q", "SR"); 567*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-16s %-4s %-8s " 568*8480SGirish.Moodalbail@Sun.COM "%-8s %-8s %-8s %-3s%</u>\n", 569*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "MODE", "STATE", 570*8480SGirish.Moodalbail@Sun.COM "TYPE", "CNT", "BYTES", "CNT"); 5718275SEric Cheng } 5728275SEric Cheng if (!(srs.srs_type & SRST_TX)) 5738275SEric Cheng return (DCMD_OK); 5748275SEric Cheng 575*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-16s %-4s " 576*8480SGirish.Moodalbail@Sun.COM "%08x %08x %-8d %-8d %-3d\n", 577*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, mac_srs_txmode2str(srs.srs_tx.st_mode), 578*8480SGirish.Moodalbail@Sun.COM srs.srs_state, srs.srs_type, srs.srs_count, srs.srs_size, 579*8480SGirish.Moodalbail@Sun.COM srs.srs_oth_ring_count); 580*8480SGirish.Moodalbail@Sun.COM break; 581*8480SGirish.Moodalbail@Sun.COM } 582*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_RXCPU: { 583*8480SGirish.Moodalbail@Sun.COM mac_cpus_t mc = srs.srs_cpu; 584*8480SGirish.Moodalbail@Sun.COM 585*8480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) { 586*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-4s %-4s " 587*8480SGirish.Moodalbail@Sun.COM "%-6s %-4s %-7s\n", 588*8480SGirish.Moodalbail@Sun.COM "", "", "NUM", "POLL", 589*8480SGirish.Moodalbail@Sun.COM "WORKER", "INTR", "FANOUT"); 590*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %-4s %-4s " 591*8480SGirish.Moodalbail@Sun.COM "%-6s %-4s %-7s%</u>\n", 592*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "CPUS", "CPU", 593*8480SGirish.Moodalbail@Sun.COM "CPU", "CPU", "CPU_CNT"); 594*8480SGirish.Moodalbail@Sun.COM } 595*8480SGirish.Moodalbail@Sun.COM if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX)) 596*8480SGirish.Moodalbail@Sun.COM return (DCMD_OK); 597*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %-4d %-4d " 598*8480SGirish.Moodalbail@Sun.COM "%-6d %-4d %-7d\n", 599*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, mc.mc_ncpus, mc.mc_pollid, 600*8480SGirish.Moodalbail@Sun.COM mc.mc_workerid, mc.mc_intr_cpu, mc.mc_fanout_cnt); 601*8480SGirish.Moodalbail@Sun.COM break; 602*8480SGirish.Moodalbail@Sun.COM 603*8480SGirish.Moodalbail@Sun.COM } 604*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_TXCPU: { 605*8480SGirish.Moodalbail@Sun.COM mac_cpus_t mc = srs.srs_cpu; 606*8480SGirish.Moodalbail@Sun.COM 607*8480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) { 608*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-4s %-6s " 609*8480SGirish.Moodalbail@Sun.COM "%-4s %-7s\n", 610*8480SGirish.Moodalbail@Sun.COM "", "", "NUM", "WORKER", 611*8480SGirish.Moodalbail@Sun.COM "INTR", "FANOUT"); 612*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %-4s %-6s " 613*8480SGirish.Moodalbail@Sun.COM "%-4s %-7s%</u>\n", 614*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "CPUS", "CPU", 615*8480SGirish.Moodalbail@Sun.COM "CPU", "CPU_CNT"); 616*8480SGirish.Moodalbail@Sun.COM } 617*8480SGirish.Moodalbail@Sun.COM if ((args & MAC_SRS_TX) && !(srs.srs_type & SRST_TX)) 618*8480SGirish.Moodalbail@Sun.COM return (DCMD_OK); 619*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %-4d " 620*8480SGirish.Moodalbail@Sun.COM "%-6d %-4d %-7d\n", 621*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, mc.mc_ncpus, 622*8480SGirish.Moodalbail@Sun.COM mc.mc_workerid, mc.mc_intr_cpu, mc.mc_fanout_cnt); 6238275SEric Cheng break; 6248275SEric Cheng } 625*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_RXCPUVERBOSE: 626*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_TXCPUVERBOSE: { 627*8480SGirish.Moodalbail@Sun.COM mac_cpus_t mc = srs.srs_cpu; 628*8480SGirish.Moodalbail@Sun.COM int cpu_index = 0, fanout_index = 0, len = 0; 629*8480SGirish.Moodalbail@Sun.COM boolean_t cpu_done = B_FALSE, fanout_done = B_FALSE; 630*8480SGirish.Moodalbail@Sun.COM 6318275SEric Cheng if (DCMD_HDRSPEC(flags)) { 632*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-20s %-20s\n", 633*8480SGirish.Moodalbail@Sun.COM "", "", "CPU_COUNT", "FANOUT_CPU_COUNT"); 634*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s " 635*8480SGirish.Moodalbail@Sun.COM "%-20s %-20s%</u>\n", 636*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", 637*8480SGirish.Moodalbail@Sun.COM "(CPU_LIST)", "(CPU_LIST)"); 6388275SEric Cheng } 639*8480SGirish.Moodalbail@Sun.COM if (((args & MAC_SRS_TX) && !(srs.srs_type & SRST_TX)) || 640*8480SGirish.Moodalbail@Sun.COM ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))) 641*8480SGirish.Moodalbail@Sun.COM return (DCMD_OK); 642*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %-20d %-20d\n", addr, mci.mci_name, 643*8480SGirish.Moodalbail@Sun.COM mc.mc_ncpus, mc.mc_fanout_cnt); 644*8480SGirish.Moodalbail@Sun.COM if (mc.mc_ncpus == 0 && mc.mc_fanout_cnt == 0) 645*8480SGirish.Moodalbail@Sun.COM break; 646*8480SGirish.Moodalbail@Sun.COM /* print all cpus and cpus for soft rings */ 647*8480SGirish.Moodalbail@Sun.COM while (!cpu_done || !fanout_done) { 648*8480SGirish.Moodalbail@Sun.COM boolean_t old_value = cpu_done; 649*8480SGirish.Moodalbail@Sun.COM 650*8480SGirish.Moodalbail@Sun.COM if (!cpu_done) { 651*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %20s ", "", ""); 652*8480SGirish.Moodalbail@Sun.COM cpu_done = mac_srs_print_cpu(&cpu_index, 653*8480SGirish.Moodalbail@Sun.COM mc.mc_ncpus, mc.mc_cpus, &len); 654*8480SGirish.Moodalbail@Sun.COM } 655*8480SGirish.Moodalbail@Sun.COM if (!fanout_done) { 656*8480SGirish.Moodalbail@Sun.COM if (old_value) 657*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-40s", "", ""); 658*8480SGirish.Moodalbail@Sun.COM else 659*8480SGirish.Moodalbail@Sun.COM mdb_printf("%*s", len, ""); 660*8480SGirish.Moodalbail@Sun.COM fanout_done = mac_srs_print_cpu(&fanout_index, 661*8480SGirish.Moodalbail@Sun.COM mc.mc_fanout_cnt, mc.mc_fanout_cpus, NULL); 662*8480SGirish.Moodalbail@Sun.COM } 663*8480SGirish.Moodalbail@Sun.COM mdb_printf("\n"); 664*8480SGirish.Moodalbail@Sun.COM } 6658275SEric Cheng break; 6668275SEric Cheng } 667*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_RXSTAT: { 668*8480SGirish.Moodalbail@Sun.COM mac_srs_rx_t srs_rx = srs.srs_rx; 669*8480SGirish.Moodalbail@Sun.COM 670*8480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) { 671*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-16s %-8s %-8s " 672*8480SGirish.Moodalbail@Sun.COM "%-8s %-8s %-8s\n", 673*8480SGirish.Moodalbail@Sun.COM "", "", "INTR", "POLL", 674*8480SGirish.Moodalbail@Sun.COM "CHAIN", "CHAIN", "CHAIN"); 675*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-16s %-8s %-8s " 676*8480SGirish.Moodalbail@Sun.COM "%-8s %-8s %-8s%</u>\n", 677*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "COUNT", "COUNT", 678*8480SGirish.Moodalbail@Sun.COM "<10", "10-50", ">50"); 679*8480SGirish.Moodalbail@Sun.COM } 680*8480SGirish.Moodalbail@Sun.COM if (srs.srs_type & SRST_TX) 681*8480SGirish.Moodalbail@Sun.COM return (DCMD_OK); 682*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-16s %-8d " 683*8480SGirish.Moodalbail@Sun.COM "%-8d %-8d " 684*8480SGirish.Moodalbail@Sun.COM "%-8d %-8d\n", 685*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, srs_rx.sr_intr_count, 686*8480SGirish.Moodalbail@Sun.COM srs_rx.sr_poll_count, srs_rx.sr_chain_cnt_undr10, 687*8480SGirish.Moodalbail@Sun.COM srs_rx.sr_chain_cnt_10to50, srs_rx.sr_chain_cnt_over50); 688*8480SGirish.Moodalbail@Sun.COM break; 689*8480SGirish.Moodalbail@Sun.COM } 690*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_TXSTAT: { 691*8480SGirish.Moodalbail@Sun.COM mac_srs_tx_t srs_tx = srs.srs_tx; 692*8480SGirish.Moodalbail@Sun.COM 693*8480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) { 694*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-5s %-8s " 695*8480SGirish.Moodalbail@Sun.COM "%-8s %-8s %-8s\n", 696*8480SGirish.Moodalbail@Sun.COM "", "", "WOKEN", "MAX", 697*8480SGirish.Moodalbail@Sun.COM "DROP", "BLOCK", "UNBLOCK"); 698*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %-5s %-8s " 699*8480SGirish.Moodalbail@Sun.COM "%-8s %-8s %-8s%</u>\n", 700*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "UP", "Q_COUNT", 701*8480SGirish.Moodalbail@Sun.COM "COUNT", "COUNT", "COUNT"); 702*8480SGirish.Moodalbail@Sun.COM } 703*8480SGirish.Moodalbail@Sun.COM if (!(srs.srs_type & SRST_TX)) 704*8480SGirish.Moodalbail@Sun.COM return (DCMD_OK); 705*8480SGirish.Moodalbail@Sun.COM 706*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %-5d " 707*8480SGirish.Moodalbail@Sun.COM "%-8d %-8d " 708*8480SGirish.Moodalbail@Sun.COM "%-8d %-8d\n", 709*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, srs.srs_tx.st_woken_up, 710*8480SGirish.Moodalbail@Sun.COM srs_tx.st_max_q_cnt, srs_tx.st_drop_count, 711*8480SGirish.Moodalbail@Sun.COM srs_tx.st_blocked_cnt, srs_tx.st_unblocked_cnt); 712*8480SGirish.Moodalbail@Sun.COM break; 713*8480SGirish.Moodalbail@Sun.COM } 714*8480SGirish.Moodalbail@Sun.COM case MAC_SRS_NONE: { 715*8480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) { 716*8480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %?s %?s %-3s%</u>\n", 717*8480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "FLENT", "HW RING", "DIR"); 718*8480SGirish.Moodalbail@Sun.COM } 719*8480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %?p %?p " 720*8480SGirish.Moodalbail@Sun.COM "%-3s ", 721*8480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, srs.srs_flent, srs.srs_ring, 722*8480SGirish.Moodalbail@Sun.COM (srs.srs_type & SRST_TX ? "TX" : "RX")); 723*8480SGirish.Moodalbail@Sun.COM break; 724*8480SGirish.Moodalbail@Sun.COM } 725*8480SGirish.Moodalbail@Sun.COM default: 726*8480SGirish.Moodalbail@Sun.COM return (DCMD_USAGE); 7278275SEric Cheng } 7288275SEric Cheng return (DCMD_OK); 7298275SEric Cheng } 7308275SEric Cheng 7318275SEric Cheng static int 7328275SEric Cheng mac_srs_walk_init(mdb_walk_state_t *wsp) 7338275SEric Cheng { 7348275SEric Cheng if (mdb_layered_walk(LAYERED_WALKER_FOR_SRS, wsp) == -1) { 7358275SEric Cheng mdb_warn("failed to walk 'mac_srs'"); 7368275SEric Cheng return (WALK_ERR); 7378275SEric Cheng } 7388275SEric Cheng return (WALK_NEXT); 7398275SEric Cheng } 7408275SEric Cheng 7418275SEric Cheng static char * 7428275SEric Cheng mac_ring_state2str(mac_ring_state_t state) 7438275SEric Cheng { 7448275SEric Cheng switch (state) { 7458275SEric Cheng case MR_FREE: 7468275SEric Cheng return ("free"); 7478275SEric Cheng case MR_NEWLY_ADDED: 7488275SEric Cheng return ("new"); 7498275SEric Cheng case MR_INUSE: 7508275SEric Cheng return ("inuse"); 7518275SEric Cheng } 7528275SEric Cheng return ("--"); 7538275SEric Cheng } 7548275SEric Cheng 7558275SEric Cheng static char * 7568275SEric Cheng mac_ring_classify2str(mac_classify_type_t classify) 7578275SEric Cheng { 7588275SEric Cheng switch (classify) { 7598275SEric Cheng case MAC_NO_CLASSIFIER: 7608275SEric Cheng return ("no"); 7618275SEric Cheng case MAC_SW_CLASSIFIER: 7628275SEric Cheng return ("sw"); 7638275SEric Cheng case MAC_HW_CLASSIFIER: 7648275SEric Cheng return ("hw"); 7658275SEric Cheng } 7668275SEric Cheng return ("--"); 7678275SEric Cheng } 7688275SEric Cheng 7698275SEric Cheng static int 7708275SEric Cheng mac_ring_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 7718275SEric Cheng { 7728275SEric Cheng mac_ring_t ring; 7738275SEric Cheng mac_group_t group; 7748275SEric Cheng flow_entry_t flent; 7758275SEric Cheng mac_soft_ring_set_t srs; 7768275SEric Cheng 7778275SEric Cheng if (!(flags & DCMD_ADDRSPEC)) { 7788275SEric Cheng if (mdb_walk_dcmd("mac_ring", "mac_ring", argc, argv) == -1) { 7798275SEric Cheng mdb_warn("failed to walk 'mac_ring'"); 7808275SEric Cheng return (DCMD_ERR); 7818275SEric Cheng } 7828275SEric Cheng return (DCMD_OK); 7838275SEric Cheng } 7848275SEric Cheng if (mdb_vread(&ring, sizeof (ring), addr) == -1) { 7858275SEric Cheng mdb_warn("failed to read struct mac_ring_s at %p", addr); 7868275SEric Cheng return (DCMD_ERR); 7878275SEric Cheng } 7888275SEric Cheng bzero(&flent, sizeof (flent)); 7898275SEric Cheng if (mdb_vread(&srs, sizeof (srs), (uintptr_t)ring.mr_srs) != -1) { 7908275SEric Cheng (void) mdb_vread(&flent, sizeof (flent), 7918275SEric Cheng (uintptr_t)srs.srs_flent); 7928275SEric Cheng } 7938275SEric Cheng (void) mdb_vread(&group, sizeof (group), (uintptr_t)ring.mr_gh); 7948275SEric Cheng if (DCMD_HDRSPEC(flags)) { 7958275SEric Cheng mdb_printf("%<u>%?s %4s %5s %4s %?s " 7968275SEric Cheng "%5s %?s %?s %s %</u>\n", 7978275SEric Cheng "ADDR", "TYPE", "STATE", "FLAG", "GROUP", 7988275SEric Cheng "CLASS", "MIP", "SRS", "FLOW NAME"); 7998275SEric Cheng } 8008275SEric Cheng mdb_printf("%?p %-4s " 8018275SEric Cheng "%5s %04x " 8028275SEric Cheng "%?p %-5s " 8038275SEric Cheng "%?p %?p %s\n", 8048275SEric Cheng addr, ((ring.mr_type == 1)? "RX" : "TX"), 8058275SEric Cheng mac_ring_state2str(ring.mr_state), ring.mr_flag, 8068275SEric Cheng ring.mr_gh, mac_ring_classify2str(ring.mr_classify_type), 8078275SEric Cheng group.mrg_mh, ring.mr_srs, flent.fe_flow_name); 8088275SEric Cheng return (DCMD_OK); 8098275SEric Cheng } 8108275SEric Cheng 8118275SEric Cheng static int 8128275SEric Cheng mac_ring_walk_init(mdb_walk_state_t *wsp) 8138275SEric Cheng { 8148275SEric Cheng if (mdb_layered_walk(LAYERED_WALKER_FOR_RING, wsp) == -1) { 8158275SEric Cheng mdb_warn("failed to walk `mac_ring`"); 8168275SEric Cheng return (WALK_ERR); 8178275SEric Cheng } 8188275SEric Cheng return (WALK_NEXT); 8198275SEric Cheng } 8208275SEric Cheng 8218275SEric Cheng static void 8228275SEric Cheng mac_ring_help(void) 8238275SEric Cheng { 8248275SEric Cheng mdb_printf("If an address is specified, then mac_ring_t " 8258275SEric Cheng "structure at that address is printed. Otherwise all the " 8268275SEric Cheng "hardware rings in the system are printed.\n"); 8278275SEric Cheng } 8288275SEric Cheng 8298275SEric Cheng /* Supported dee-commands */ 8308275SEric Cheng static const mdb_dcmd_t dcmds[] = { 8318275SEric Cheng {"mac_flow", "?[-u] [-aprtsm]", "display Flow Entry structures", 8328275SEric Cheng mac_flow_dcmd, mac_flow_help}, 833*8480SGirish.Moodalbail@Sun.COM {"mac_srs", "?[ -r[s|c[v]] | -t[s|c[v]] ]", "display MAC Soft Ring Set" 834*8480SGirish.Moodalbail@Sun.COM " structures", mac_srs_dcmd, mac_srs_help}, 8358275SEric Cheng {"mac_ring", "?", "display MAC ring (hardware) structures", 8368275SEric Cheng mac_ring_dcmd, mac_ring_help}, 8378275SEric Cheng { NULL } 8388275SEric Cheng }; 8398275SEric Cheng 8408275SEric Cheng /* Supported walkers */ 8418275SEric Cheng static const mdb_walker_t walkers[] = { 8428275SEric Cheng {"mac_flow", "walk list of flow entry structures", mac_flow_walk_init, 8438275SEric Cheng mac_common_walk_step, NULL, NULL}, 8448275SEric Cheng {"mac_srs", "walk list of mac soft ring set structures", 8458275SEric Cheng mac_srs_walk_init, mac_common_walk_step, NULL, NULL}, 8468275SEric Cheng {"mac_ring", "walk list of mac ring structures", mac_ring_walk_init, 8478275SEric Cheng mac_common_walk_step, NULL, NULL}, 8488275SEric Cheng { NULL } 8498275SEric Cheng }; 8508275SEric Cheng 8518275SEric Cheng static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 8528275SEric Cheng 8538275SEric Cheng const mdb_modinfo_t * 8548275SEric Cheng _mdb_init(void) 8558275SEric Cheng { 8568275SEric Cheng return (&modinfo); 8578275SEric Cheng } 858