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*11878SVenu.Iyer@Sun.COM * Copyright 2010 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>
37*11878SVenu.Iyer@Sun.COM #include <sys/mac_stat.h>
388275SEric Cheng
398275SEric Cheng #define STRSIZE 64
408275SEric Cheng #define MAC_RX_SRS_SIZE (MAX_RINGS_PER_GROUP * sizeof (uintptr_t))
418275SEric Cheng
428275SEric Cheng #define LAYERED_WALKER_FOR_FLOW "flow_entry_cache"
438275SEric Cheng #define LAYERED_WALKER_FOR_SRS "mac_srs_cache"
448275SEric Cheng #define LAYERED_WALKER_FOR_RING "mac_ring_cache"
458275SEric Cheng
468275SEric Cheng /* arguments passed to mac_flow dee-command */
478275SEric Cheng #define MAC_FLOW_NONE 0x01
488275SEric Cheng #define MAC_FLOW_ATTR 0x02
498275SEric Cheng #define MAC_FLOW_PROP 0x04
508275SEric Cheng #define MAC_FLOW_RX 0x08
518275SEric Cheng #define MAC_FLOW_TX 0x10
528275SEric Cheng #define MAC_FLOW_USER 0x20
538275SEric Cheng #define MAC_FLOW_STATS 0x40
548275SEric Cheng #define MAC_FLOW_MISC 0x80
558275SEric Cheng
568275SEric Cheng /* arguments passed to mac_srs dee-command */
578480SGirish.Moodalbail@Sun.COM #define MAC_SRS_NONE 0x00
588480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RX 0x01
598480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TX 0x02
608480SGirish.Moodalbail@Sun.COM #define MAC_SRS_STAT 0x04
618480SGirish.Moodalbail@Sun.COM #define MAC_SRS_CPU 0x08
628480SGirish.Moodalbail@Sun.COM #define MAC_SRS_VERBOSE 0x10
63*11878SVenu.Iyer@Sun.COM #define MAC_SRS_INTR 0x20
648480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RXSTAT (MAC_SRS_RX|MAC_SRS_STAT)
658480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TXSTAT (MAC_SRS_TX|MAC_SRS_STAT)
668480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RXCPU (MAC_SRS_RX|MAC_SRS_CPU)
678480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TXCPU (MAC_SRS_TX|MAC_SRS_CPU)
688480SGirish.Moodalbail@Sun.COM #define MAC_SRS_RXCPUVERBOSE (MAC_SRS_RXCPU|MAC_SRS_VERBOSE)
698480SGirish.Moodalbail@Sun.COM #define MAC_SRS_TXCPUVERBOSE (MAC_SRS_TXCPU|MAC_SRS_VERBOSE)
70*11878SVenu.Iyer@Sun.COM #define MAC_SRS_RXINTR (MAC_SRS_RX|MAC_SRS_INTR)
71*11878SVenu.Iyer@Sun.COM #define MAC_SRS_TXINTR (MAC_SRS_TX|MAC_SRS_INTR)
728275SEric Cheng
738275SEric Cheng static char *
mac_flow_proto2str(uint8_t protocol)748275SEric Cheng mac_flow_proto2str(uint8_t protocol)
758275SEric Cheng {
768275SEric Cheng switch (protocol) {
778275SEric Cheng case IPPROTO_TCP:
788275SEric Cheng return ("tcp");
798275SEric Cheng case IPPROTO_UDP:
808275SEric Cheng return ("udp");
818275SEric Cheng case IPPROTO_SCTP:
828275SEric Cheng return ("sctp");
838275SEric Cheng case IPPROTO_ICMP:
848275SEric Cheng return ("icmp");
858275SEric Cheng case IPPROTO_ICMPV6:
868275SEric Cheng return ("icmpv6");
878275SEric Cheng default:
888275SEric Cheng return ("--");
898275SEric Cheng }
908275SEric Cheng }
918275SEric Cheng
928275SEric Cheng static char *
mac_flow_priority2str(mac_priority_level_t prio)938275SEric Cheng mac_flow_priority2str(mac_priority_level_t prio)
948275SEric Cheng {
958275SEric Cheng switch (prio) {
968275SEric Cheng case MPL_LOW:
978275SEric Cheng return ("low");
988275SEric Cheng case MPL_MEDIUM:
998275SEric Cheng return ("medium");
1008275SEric Cheng case MPL_HIGH:
1018275SEric Cheng return ("high");
1028275SEric Cheng case MPL_RESET:
1038275SEric Cheng return ("reset");
1048275SEric Cheng default:
1058275SEric Cheng return ("--");
1068275SEric Cheng }
1078275SEric Cheng }
1088275SEric Cheng
1098275SEric Cheng /*
1108275SEric Cheng * Convert bandwidth in bps to a string in mpbs.
1118275SEric Cheng */
1128275SEric Cheng static char *
mac_flow_bw2str(uint64_t bw,char * buf,ssize_t len)1138275SEric Cheng mac_flow_bw2str(uint64_t bw, char *buf, ssize_t len)
1148275SEric Cheng {
1158275SEric Cheng int kbps, mbps;
1168275SEric Cheng
1178275SEric Cheng kbps = (bw % 1000000)/1000;
1188275SEric Cheng mbps = bw/1000000;
1198275SEric Cheng if ((mbps == 0) && (kbps != 0))
1208275SEric Cheng mdb_snprintf(buf, len, "0.%03u", kbps);
1218275SEric Cheng else
1228275SEric Cheng mdb_snprintf(buf, len, "%5u", mbps);
1238275SEric Cheng return (buf);
1248275SEric Cheng }
1258275SEric Cheng
1268275SEric Cheng static void
mac_flow_print_header(uint_t args)1278275SEric Cheng mac_flow_print_header(uint_t args)
1288275SEric Cheng {
1298275SEric Cheng switch (args) {
1308275SEric Cheng case MAC_FLOW_NONE:
1318999SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %4s %?s %?s %-16s\n",
1328999SGirish.Moodalbail@Sun.COM "", "", "LINK", "", "", "MIP");
1338999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %4s %?s %?s %-16s%</u>\n",
1348999SGirish.Moodalbail@Sun.COM "ADDR", "FLOW NAME", "ID", "MCIP", "MIP", "NAME");
1358275SEric Cheng break;
1368275SEric Cheng case MAC_FLOW_ATTR:
1378275SEric Cheng mdb_printf("%<u>%?s %-32s %-7s %6s "
1388275SEric Cheng "%-9s %s%</u>\n",
1398275SEric Cheng "ADDR", "FLOW NAME", "PROTO", "PORT",
1408275SEric Cheng "DSFLD:MSK", "IPADDR");
1418275SEric Cheng break;
1428275SEric Cheng case MAC_FLOW_PROP:
1438275SEric Cheng mdb_printf("%<u>%?s %-32s %8s %9s%</u>\n",
1448275SEric Cheng "ADDR", "FLOW NAME", "MAXBW(M)", "PRIORITY");
1458275SEric Cheng break;
1468275SEric Cheng case MAC_FLOW_MISC:
1478999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-24s %10s %10s "
1488999SGirish.Moodalbail@Sun.COM "%20s %4s%</u>\n",
1498275SEric Cheng "ADDR", "FLOW NAME", "TYPE", "FLAGS",
1508275SEric Cheng "MATCH_FN", "ZONE");
1518275SEric Cheng break;
1528275SEric Cheng case MAC_FLOW_RX:
1538999SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-24s %3s %s\n", "", "", "SRS", "RX");
1548999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-24s %3s %s%</u>\n",
1558999SGirish.Moodalbail@Sun.COM "ADDR", "FLOW NAME", "CNT", "SRS");
1568275SEric Cheng break;
1578275SEric Cheng case MAC_FLOW_TX:
1588275SEric Cheng mdb_printf("%<u>%?s %-32s %?s %</u>\n",
1598275SEric Cheng "ADDR", "FLOW NAME", "TX_SRS");
1608275SEric Cheng break;
1618275SEric Cheng case MAC_FLOW_STATS:
1628999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-32s %16s %16s%</u>\n",
1638275SEric Cheng "ADDR", "FLOW NAME", "RBYTES", "OBYTES");
1648275SEric Cheng break;
1658275SEric Cheng }
1668275SEric Cheng }
1678275SEric Cheng
1688275SEric Cheng /*
1698275SEric Cheng * Display selected fields of the flow_entry_t structure
1708275SEric Cheng */
1718275SEric Cheng static int
mac_flow_dcmd_output(uintptr_t addr,uint_t flags,uint_t args)1728275SEric Cheng mac_flow_dcmd_output(uintptr_t addr, uint_t flags, uint_t args)
1738275SEric Cheng {
1748275SEric Cheng static const mdb_bitmask_t flow_type_bits[] = {
1758275SEric Cheng {"P", FLOW_PRIMARY_MAC, FLOW_PRIMARY_MAC},
1768275SEric Cheng {"V", FLOW_VNIC_MAC, FLOW_VNIC_MAC},
1778275SEric Cheng {"M", FLOW_MCAST, FLOW_MCAST},
1788275SEric Cheng {"O", FLOW_OTHER, FLOW_OTHER},
1798275SEric Cheng {"U", FLOW_USER, FLOW_USER},
1808275SEric Cheng {"V", FLOW_VNIC, FLOW_VNIC},
1818275SEric Cheng {"NS", FLOW_NO_STATS, FLOW_NO_STATS},
1828275SEric Cheng { NULL, 0, 0 }
1838275SEric Cheng };
1848275SEric Cheng #define FLOW_MAX_TYPE (sizeof (flow_type_bits) / sizeof (mdb_bitmask_t))
1858275SEric Cheng
1868275SEric Cheng static const mdb_bitmask_t flow_flag_bits[] = {
1878275SEric Cheng {"Q", FE_QUIESCE, FE_QUIESCE},
1888275SEric Cheng {"W", FE_WAITER, FE_WAITER},
1898275SEric Cheng {"T", FE_FLOW_TAB, FE_FLOW_TAB},
1908275SEric Cheng {"G", FE_G_FLOW_HASH, FE_G_FLOW_HASH},
1918275SEric Cheng {"I", FE_INCIPIENT, FE_INCIPIENT},
1928275SEric Cheng {"C", FE_CONDEMNED, FE_CONDEMNED},
1938275SEric Cheng {"NU", FE_UF_NO_DATAPATH, FE_UF_NO_DATAPATH},
1948275SEric Cheng {"NC", FE_MC_NO_DATAPATH, FE_MC_NO_DATAPATH},
1958275SEric Cheng { NULL, 0, 0 }
1968275SEric Cheng };
1978275SEric Cheng #define FLOW_MAX_FLAGS (sizeof (flow_flag_bits) / sizeof (mdb_bitmask_t))
1988275SEric Cheng flow_entry_t fe;
1998275SEric Cheng mac_client_impl_t mcip;
2008275SEric Cheng mac_impl_t mip;
2018275SEric Cheng
2028275SEric Cheng if (mdb_vread(&fe, sizeof (fe), addr) == -1) {
2038275SEric Cheng mdb_warn("failed to read struct flow_entry_s at %p", addr);
2048275SEric Cheng return (DCMD_ERR);
2058275SEric Cheng }
2068275SEric Cheng if (args & MAC_FLOW_USER) {
2078275SEric Cheng args &= ~MAC_FLOW_USER;
2088275SEric Cheng if (fe.fe_type & FLOW_MCAST) {
2098275SEric Cheng if (DCMD_HDRSPEC(flags))
2108275SEric Cheng mac_flow_print_header(args);
2118275SEric Cheng return (DCMD_OK);
2128275SEric Cheng }
2138275SEric Cheng }
2148275SEric Cheng if (DCMD_HDRSPEC(flags))
2158275SEric Cheng mac_flow_print_header(args);
2168275SEric Cheng bzero(&mcip, sizeof (mcip));
2178275SEric Cheng bzero(&mip, sizeof (mip));
2188275SEric Cheng if (fe.fe_mcip != NULL && mdb_vread(&mcip, sizeof (mcip),
2198275SEric Cheng (uintptr_t)fe.fe_mcip) == sizeof (mcip)) {
2208275SEric Cheng (void) mdb_vread(&mip, sizeof (mip), (uintptr_t)mcip.mci_mip);
2218275SEric Cheng }
2228275SEric Cheng switch (args) {
2238275SEric Cheng case MAC_FLOW_NONE: {
2248999SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %4d %?p "
2258999SGirish.Moodalbail@Sun.COM "%?p %-16s\n",
2268275SEric Cheng addr, fe.fe_flow_name, fe.fe_link_id, fe.fe_mcip,
2278275SEric Cheng mcip.mci_mip, mip.mi_name);
2288275SEric Cheng break;
2298275SEric Cheng }
2308275SEric Cheng case MAC_FLOW_ATTR: {
2318275SEric Cheng struct in_addr in4;
2328275SEric Cheng uintptr_t desc_addr;
2338275SEric Cheng flow_desc_t fdesc;
2348275SEric Cheng
2358275SEric Cheng desc_addr = addr + OFFSETOF(flow_entry_t, fe_flow_desc);
2368275SEric Cheng if (mdb_vread(&fdesc, sizeof (fdesc), desc_addr) == -1) {
2378275SEric Cheng mdb_warn("failed to read struct flow_description at %p",
2388275SEric Cheng desc_addr);
2398275SEric Cheng return (DCMD_ERR);
2408275SEric Cheng }
2418275SEric Cheng mdb_printf("%?p %-32s "
2428999SGirish.Moodalbail@Sun.COM "%-7s %6d "
2438275SEric Cheng "%4d:%-4d ",
2448275SEric Cheng addr, fe.fe_flow_name,
2458275SEric Cheng mac_flow_proto2str(fdesc.fd_protocol), fdesc.fd_local_port,
2468275SEric Cheng fdesc.fd_dsfield, fdesc.fd_dsfield_mask);
2478275SEric Cheng if (fdesc.fd_ipversion == IPV4_VERSION) {
2488275SEric Cheng IN6_V4MAPPED_TO_INADDR(&fdesc.fd_local_addr, &in4);
2498275SEric Cheng mdb_printf("%I", in4.s_addr);
2508275SEric Cheng } else if (fdesc.fd_ipversion == IPV6_VERSION) {
2518275SEric Cheng mdb_printf("%N", &fdesc.fd_local_addr);
2528275SEric Cheng } else {
2538275SEric Cheng mdb_printf("%s", "--");
2548275SEric Cheng }
2558275SEric Cheng mdb_printf("\n");
2568275SEric Cheng break;
2578275SEric Cheng }
2588275SEric Cheng case MAC_FLOW_PROP: {
2598275SEric Cheng uintptr_t prop_addr;
2608275SEric Cheng char bwstr[STRSIZE];
2618275SEric Cheng mac_resource_props_t fprop;
2628275SEric Cheng
2638275SEric Cheng prop_addr = addr + OFFSETOF(flow_entry_t, fe_resource_props);
2648275SEric Cheng if (mdb_vread(&fprop, sizeof (fprop), prop_addr) == -1) {
2658275SEric Cheng mdb_warn("failed to read struct mac_resoource_props "
2668275SEric Cheng "at %p", prop_addr);
2678275SEric Cheng return (DCMD_ERR);
2688275SEric Cheng }
2698275SEric Cheng mdb_printf("%?p %-32s "
2708275SEric Cheng "%8s %9s\n",
2718275SEric Cheng addr, fe.fe_flow_name,
2728275SEric Cheng mac_flow_bw2str(fprop.mrp_maxbw, bwstr, STRSIZE),
2738275SEric Cheng mac_flow_priority2str(fprop.mrp_priority));
2748275SEric Cheng break;
2758275SEric Cheng }
2768275SEric Cheng case MAC_FLOW_MISC: {
2778275SEric Cheng char flow_flags[2 * FLOW_MAX_FLAGS];
2788275SEric Cheng char flow_type[2 * FLOW_MAX_TYPE];
2798275SEric Cheng GElf_Sym sym;
2808275SEric Cheng char func_name[MDB_SYM_NAMLEN] = "";
2818275SEric Cheng uintptr_t func, match_addr;
2828275SEric Cheng
2838275SEric Cheng match_addr = addr + OFFSETOF(flow_entry_t, fe_match);
2848275SEric Cheng (void) mdb_vread(&func, sizeof (func), match_addr);
2858275SEric Cheng (void) mdb_lookup_by_addr(func, MDB_SYM_EXACT, func_name,
2868275SEric Cheng MDB_SYM_NAMLEN, &sym);
2878275SEric Cheng mdb_snprintf(flow_flags, 2 * FLOW_MAX_FLAGS, "%hb",
2888275SEric Cheng fe.fe_flags, flow_flag_bits);
2898275SEric Cheng mdb_snprintf(flow_type, 2 * FLOW_MAX_TYPE, "%hb",
2908275SEric Cheng fe.fe_type, flow_type_bits);
29110616SSebastien.Roy@Sun.COM mdb_printf("%?p %-24s %10s %10s %20s\n",
29210616SSebastien.Roy@Sun.COM addr, fe.fe_flow_name, flow_type, flow_flags, func_name);
2938275SEric Cheng break;
2948275SEric Cheng }
2958275SEric Cheng case MAC_FLOW_RX: {
2968480SGirish.Moodalbail@Sun.COM uintptr_t rxaddr, rx_srs[MAX_RINGS_PER_GROUP] = {0};
2978275SEric Cheng int i;
2988275SEric Cheng
2998275SEric Cheng rxaddr = addr + OFFSETOF(flow_entry_t, fe_rx_srs);
3008275SEric Cheng (void) mdb_vread(rx_srs, MAC_RX_SRS_SIZE, rxaddr);
3018999SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-24s %3d ",
3028480SGirish.Moodalbail@Sun.COM addr, fe.fe_flow_name, fe.fe_rx_srs_cnt);
3038275SEric Cheng for (i = 0; i < MAX_RINGS_PER_GROUP; i++) {
3048275SEric Cheng if (rx_srs[i] == 0)
3058275SEric Cheng continue;
3068275SEric Cheng mdb_printf("%p ", rx_srs[i]);
3078275SEric Cheng }
3088275SEric Cheng mdb_printf("\n");
3098275SEric Cheng break;
3108275SEric Cheng }
3118275SEric Cheng case MAC_FLOW_TX: {
3128275SEric Cheng uintptr_t tx_srs = 0, txaddr;
3138275SEric Cheng
3148275SEric Cheng txaddr = addr + OFFSETOF(flow_entry_t, fe_tx_srs);
3158275SEric Cheng (void) mdb_vread(&tx_srs, sizeof (uintptr_t), txaddr);
3168275SEric Cheng mdb_printf("%?p %-32s %?p\n",
3178275SEric Cheng addr, fe.fe_flow_name, fe.fe_tx_srs);
3188275SEric Cheng break;
3198275SEric Cheng }
3208275SEric Cheng case MAC_FLOW_STATS: {
321*11878SVenu.Iyer@Sun.COM uint64_t totibytes = 0;
322*11878SVenu.Iyer@Sun.COM uint64_t totobytes = 0;
323*11878SVenu.Iyer@Sun.COM mac_soft_ring_set_t *mac_srs;
324*11878SVenu.Iyer@Sun.COM mac_rx_stats_t *mac_rx_stat;
325*11878SVenu.Iyer@Sun.COM mac_tx_stats_t *mac_tx_stat;
326*11878SVenu.Iyer@Sun.COM int i;
327*11878SVenu.Iyer@Sun.COM
328*11878SVenu.Iyer@Sun.COM for (i = 0; i < fe.fe_rx_srs_cnt; i++) {
329*11878SVenu.Iyer@Sun.COM mac_srs = (mac_soft_ring_set_t *)(fe.fe_rx_srs[i]);
330*11878SVenu.Iyer@Sun.COM mac_rx_stat = &mac_srs->srs_rx.sr_stat;
331*11878SVenu.Iyer@Sun.COM totibytes += mac_rx_stat->mrs_intrbytes +
332*11878SVenu.Iyer@Sun.COM mac_rx_stat->mrs_pollbytes +
333*11878SVenu.Iyer@Sun.COM mac_rx_stat->mrs_lclbytes;
334*11878SVenu.Iyer@Sun.COM }
335*11878SVenu.Iyer@Sun.COM mac_srs = (mac_soft_ring_set_t *)(fe.fe_tx_srs);
336*11878SVenu.Iyer@Sun.COM if (mac_srs != NULL) {
337*11878SVenu.Iyer@Sun.COM mac_tx_stat = &mac_srs->srs_tx.st_stat;
338*11878SVenu.Iyer@Sun.COM totobytes = mac_tx_stat->mts_obytes;
339*11878SVenu.Iyer@Sun.COM }
3408275SEric Cheng mdb_printf("%?p %-32s %16llu %16llu\n",
341*11878SVenu.Iyer@Sun.COM addr, fe.fe_flow_name, totibytes, totobytes);
342*11878SVenu.Iyer@Sun.COM
3438275SEric Cheng break;
3448275SEric Cheng }
3458275SEric Cheng }
3468275SEric Cheng return (DCMD_OK);
3478275SEric Cheng }
3488275SEric Cheng
3498275SEric Cheng /*
3508275SEric Cheng * Parse the arguments passed to the dcmd and print all or one flow_entry_t
3518275SEric Cheng * structures
3528275SEric Cheng */
3538275SEric Cheng static int
mac_flow_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3548275SEric Cheng mac_flow_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3558275SEric Cheng {
3568275SEric Cheng uint_t args = 0;
3578275SEric Cheng
3588275SEric Cheng if (!(flags & DCMD_ADDRSPEC)) {
3598275SEric Cheng if (mdb_walk_dcmd("mac_flow", "mac_flow", argc, argv) == -1) {
3608275SEric Cheng mdb_warn("failed to walk 'mac_flow'");
3618275SEric Cheng return (DCMD_ERR);
3628275SEric Cheng }
3638275SEric Cheng return (DCMD_OK);
3648275SEric Cheng }
3658275SEric Cheng if ((mdb_getopts(argc, argv,
3668275SEric Cheng 'a', MDB_OPT_SETBITS, MAC_FLOW_ATTR, &args,
3678275SEric Cheng 'p', MDB_OPT_SETBITS, MAC_FLOW_PROP, &args,
3688275SEric Cheng 'm', MDB_OPT_SETBITS, MAC_FLOW_MISC, &args,
3698275SEric Cheng 'r', MDB_OPT_SETBITS, MAC_FLOW_RX, &args,
3708275SEric Cheng 't', MDB_OPT_SETBITS, MAC_FLOW_TX, &args,
3718275SEric Cheng 's', MDB_OPT_SETBITS, MAC_FLOW_STATS, &args,
3728275SEric Cheng 'u', MDB_OPT_SETBITS, MAC_FLOW_USER, &args) != argc)) {
3738275SEric Cheng return (DCMD_USAGE);
3748275SEric Cheng }
3758275SEric Cheng if (argc > 2 || (argc == 2 && !(args & MAC_FLOW_USER)))
3768275SEric Cheng return (DCMD_USAGE);
3778275SEric Cheng /*
3788275SEric Cheng * If no arguments was specified or just "-u" was specified then
3798275SEric Cheng * we default to printing basic information of flows.
3808275SEric Cheng */
3818275SEric Cheng if (args == 0 || args == MAC_FLOW_USER)
3828275SEric Cheng args |= MAC_FLOW_NONE;
3838275SEric Cheng
3848275SEric Cheng return (mac_flow_dcmd_output(addr, flags, args));
3858275SEric Cheng }
3868275SEric Cheng
3878275SEric Cheng static void
mac_flow_help(void)3888275SEric Cheng mac_flow_help(void)
3898275SEric Cheng {
3908275SEric Cheng mdb_printf("If an address is specified, then flow_entry structure at "
3918275SEric Cheng "that address is printed. Otherwise all the flows in the system "
3928275SEric Cheng "are printed.\n");
3938275SEric Cheng mdb_printf("Options:\n"
3948275SEric Cheng "\t-u\tdisplay user defined link & vnic flows.\n"
3958275SEric Cheng "\t-a\tdisplay flow attributes\n"
3968275SEric Cheng "\t-p\tdisplay flow properties\n"
3978275SEric Cheng "\t-r\tdisplay rx side information\n"
3988275SEric Cheng "\t-t\tdisplay tx side information\n"
3998275SEric Cheng "\t-s\tdisplay flow statistics\n"
4008275SEric Cheng "\t-m\tdisplay miscellaneous flow information\n\n");
4018275SEric Cheng mdb_printf("%<u>Interpreting Flow type and Flow flags output.%</u>\n");
4028275SEric Cheng mdb_printf("Flow Types:\n");
4038275SEric Cheng mdb_printf("\t P --> FLOW_PRIMARY_MAC\n");
4048275SEric Cheng mdb_printf("\t V --> FLOW_VNIC_MAC\n");
4058275SEric Cheng mdb_printf("\t M --> FLOW_MCAST\n");
4068275SEric Cheng mdb_printf("\t O --> FLOW_OTHER\n");
4078275SEric Cheng mdb_printf("\t U --> FLOW_USER\n");
4088275SEric Cheng mdb_printf("\t NS --> FLOW_NO_STATS\n\n");
4098275SEric Cheng mdb_printf("Flow Flags:\n");
4108275SEric Cheng mdb_printf("\t Q --> FE_QUIESCE\n");
4118275SEric Cheng mdb_printf("\t W --> FE_WAITER\n");
4128275SEric Cheng mdb_printf("\t T --> FE_FLOW_TAB\n");
4138275SEric Cheng mdb_printf("\t G --> FE_G_FLOW_HASH\n");
4148275SEric Cheng mdb_printf("\t I --> FE_INCIPIENT\n");
4158275SEric Cheng mdb_printf("\t C --> FE_CONDEMNED\n");
4168275SEric Cheng mdb_printf("\t NU --> FE_UF_NO_DATAPATH\n");
4178275SEric Cheng mdb_printf("\t NC --> FE_MC_NO_DATAPATH\n");
4188275SEric Cheng }
4198275SEric Cheng
4208275SEric Cheng /*
4218275SEric Cheng * called once by the debugger when the mac_flow walk begins.
4228275SEric Cheng */
4238275SEric Cheng static int
mac_flow_walk_init(mdb_walk_state_t * wsp)4248275SEric Cheng mac_flow_walk_init(mdb_walk_state_t *wsp)
4258275SEric Cheng {
4268275SEric Cheng if (mdb_layered_walk(LAYERED_WALKER_FOR_FLOW, wsp) == -1) {
4278275SEric Cheng mdb_warn("failed to walk 'mac_flow'");
4288275SEric Cheng return (WALK_ERR);
4298275SEric Cheng }
4308275SEric Cheng return (WALK_NEXT);
4318275SEric Cheng }
4328275SEric Cheng
4338275SEric Cheng /*
4348275SEric Cheng * Common walker step funciton for flow_entry_t, mac_soft_ring_set_t and
4358275SEric Cheng * mac_ring_t.
4368275SEric Cheng *
4378275SEric Cheng * Steps through each flow_entry_t and calls the callback function. If the
4388275SEric Cheng * user executed ::walk mac_flow, it just prints the address or if the user
4398275SEric Cheng * executed ::mac_flow it displays selected fields of flow_entry_t structure
4408275SEric Cheng * by calling "mac_flow_dcmd"
4418275SEric Cheng */
4428275SEric Cheng static int
mac_common_walk_step(mdb_walk_state_t * wsp)4438275SEric Cheng mac_common_walk_step(mdb_walk_state_t *wsp)
4448275SEric Cheng {
4458275SEric Cheng int status;
4468275SEric Cheng
4478275SEric Cheng if (wsp->walk_addr == NULL)
4488275SEric Cheng return (WALK_DONE);
4498275SEric Cheng
4508275SEric Cheng status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
4518275SEric Cheng wsp->walk_cbdata);
4528275SEric Cheng
4538275SEric Cheng return (status);
4548275SEric Cheng }
4558275SEric Cheng
4568275SEric Cheng static char *
mac_srs_txmode2str(mac_tx_srs_mode_t mode)4578275SEric Cheng mac_srs_txmode2str(mac_tx_srs_mode_t mode)
4588275SEric Cheng {
4598275SEric Cheng switch (mode) {
4608275SEric Cheng case SRS_TX_DEFAULT:
4618480SGirish.Moodalbail@Sun.COM return ("DEF");
4628275SEric Cheng case SRS_TX_SERIALIZE:
4638480SGirish.Moodalbail@Sun.COM return ("SER");
4648275SEric Cheng case SRS_TX_FANOUT:
4658480SGirish.Moodalbail@Sun.COM return ("FO");
4668275SEric Cheng case SRS_TX_BW:
4678480SGirish.Moodalbail@Sun.COM return ("BW");
4688275SEric Cheng case SRS_TX_BW_FANOUT:
4698480SGirish.Moodalbail@Sun.COM return ("BWFO");
470*11878SVenu.Iyer@Sun.COM case SRS_TX_AGGR:
471*11878SVenu.Iyer@Sun.COM return ("AG");
472*11878SVenu.Iyer@Sun.COM case SRS_TX_BW_AGGR:
473*11878SVenu.Iyer@Sun.COM return ("BWAG");
4748275SEric Cheng }
4758275SEric Cheng return ("--");
4768275SEric Cheng }
4778275SEric Cheng
4788275SEric Cheng static void
mac_srs_help(void)4798275SEric Cheng mac_srs_help(void)
4808275SEric Cheng {
4818275SEric Cheng mdb_printf("If an address is specified, then mac_soft_ring_set "
4828275SEric Cheng "structure at that address is printed. Otherwise all the "
4838275SEric Cheng "SRS in the system are printed.\n");
4848275SEric Cheng mdb_printf("Options:\n"
4858275SEric Cheng "\t-r\tdisplay recieve side SRS structures\n"
4868480SGirish.Moodalbail@Sun.COM "\t-t\tdisplay transmit side SRS structures\n"
4878480SGirish.Moodalbail@Sun.COM "\t-s\tdisplay statistics for RX or TX side\n"
4888480SGirish.Moodalbail@Sun.COM "\t-c\tdisplay CPU binding for RX or TX side\n"
4898480SGirish.Moodalbail@Sun.COM "\t-v\tverbose flag for CPU binding to list cpus\n"
490*11878SVenu.Iyer@Sun.COM "\t-i\tdisplay mac_ring_t and interrupt information\n"
4918480SGirish.Moodalbail@Sun.COM "Note: use -r or -t (to specify RX or TX side respectively) along "
4928480SGirish.Moodalbail@Sun.COM "with -c or -s\n");
4938480SGirish.Moodalbail@Sun.COM mdb_printf("\n%<u>Interpreting TX Modes%</u>\n");
4948480SGirish.Moodalbail@Sun.COM mdb_printf("\t DEF --> Default\n");
4958480SGirish.Moodalbail@Sun.COM mdb_printf("\t SER --> Serialize\n");
4968480SGirish.Moodalbail@Sun.COM mdb_printf("\t FO --> Fanout\n");
4978480SGirish.Moodalbail@Sun.COM mdb_printf("\t BW --> Bandwidth\n");
4988480SGirish.Moodalbail@Sun.COM mdb_printf("\tBWFO --> Bandwidth Fanout\n");
499*11878SVenu.Iyer@Sun.COM mdb_printf("\t AG --> Aggr\n");
500*11878SVenu.Iyer@Sun.COM mdb_printf("\tBWAG --> Bandwidth Aggr\n");
5018480SGirish.Moodalbail@Sun.COM }
5028480SGirish.Moodalbail@Sun.COM
5038480SGirish.Moodalbail@Sun.COM /*
5048480SGirish.Moodalbail@Sun.COM * In verbose mode "::mac_srs -rcv or ::mac_srs -tcv", we print the CPUs
5058480SGirish.Moodalbail@Sun.COM * assigned to a link and CPUS assigned to the soft rings.
5068480SGirish.Moodalbail@Sun.COM * 'len' is used for formatting the output and represents the number of
5078480SGirish.Moodalbail@Sun.COM * spaces between CPU list and Fanout CPU list in the output.
5088480SGirish.Moodalbail@Sun.COM */
5098480SGirish.Moodalbail@Sun.COM static boolean_t
mac_srs_print_cpu(int * i,uint32_t cnt,uint32_t * cpu_list,int * len)5108480SGirish.Moodalbail@Sun.COM mac_srs_print_cpu(int *i, uint32_t cnt, uint32_t *cpu_list, int *len)
5118480SGirish.Moodalbail@Sun.COM {
5128480SGirish.Moodalbail@Sun.COM int num = 0;
5138480SGirish.Moodalbail@Sun.COM
5148480SGirish.Moodalbail@Sun.COM if (*i == 0)
5158480SGirish.Moodalbail@Sun.COM mdb_printf("(");
5168480SGirish.Moodalbail@Sun.COM else
5178480SGirish.Moodalbail@Sun.COM mdb_printf(" ");
5188480SGirish.Moodalbail@Sun.COM while (*i < cnt) {
5198480SGirish.Moodalbail@Sun.COM /* We print 6 CPU's at a time to keep display within 80 cols */
5208480SGirish.Moodalbail@Sun.COM if (((num + 1) % 7) == 0) {
5218480SGirish.Moodalbail@Sun.COM if (len != NULL)
5228480SGirish.Moodalbail@Sun.COM *len = 2;
5238480SGirish.Moodalbail@Sun.COM return (B_FALSE);
5248480SGirish.Moodalbail@Sun.COM }
5258480SGirish.Moodalbail@Sun.COM mdb_printf("%02x%c", cpu_list[*i], ((*i == cnt - 1)?')':','));
5268480SGirish.Moodalbail@Sun.COM ++*i;
5278480SGirish.Moodalbail@Sun.COM ++num;
5288480SGirish.Moodalbail@Sun.COM }
5298480SGirish.Moodalbail@Sun.COM if (len != NULL)
5308480SGirish.Moodalbail@Sun.COM *len = (7 - num) * 3;
5318480SGirish.Moodalbail@Sun.COM return (B_TRUE);
5328275SEric Cheng }
5338275SEric Cheng
5348275SEric Cheng static int
mac_srs_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5358275SEric Cheng mac_srs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5368275SEric Cheng {
5378480SGirish.Moodalbail@Sun.COM uint_t args = MAC_SRS_NONE;
5388275SEric Cheng mac_soft_ring_set_t srs;
5398480SGirish.Moodalbail@Sun.COM mac_client_impl_t mci;
5408275SEric Cheng
5418275SEric Cheng if (!(flags & DCMD_ADDRSPEC)) {
5428275SEric Cheng if (mdb_walk_dcmd("mac_srs", "mac_srs", argc, argv) == -1) {
5438275SEric Cheng mdb_warn("failed to walk 'mac_srs'");
5448275SEric Cheng return (DCMD_ERR);
5458275SEric Cheng }
5468275SEric Cheng return (DCMD_OK);
5478275SEric Cheng }
5488480SGirish.Moodalbail@Sun.COM if (mdb_getopts(argc, argv,
5498275SEric Cheng 'r', MDB_OPT_SETBITS, MAC_SRS_RX, &args,
5508480SGirish.Moodalbail@Sun.COM 't', MDB_OPT_SETBITS, MAC_SRS_TX, &args,
5518480SGirish.Moodalbail@Sun.COM 'c', MDB_OPT_SETBITS, MAC_SRS_CPU, &args,
5528480SGirish.Moodalbail@Sun.COM 'v', MDB_OPT_SETBITS, MAC_SRS_VERBOSE, &args,
553*11878SVenu.Iyer@Sun.COM 'i', MDB_OPT_SETBITS, MAC_SRS_INTR, &args,
5548480SGirish.Moodalbail@Sun.COM 's', MDB_OPT_SETBITS, MAC_SRS_STAT, &args) != argc) {
5558275SEric Cheng return (DCMD_USAGE);
5568275SEric Cheng }
5578480SGirish.Moodalbail@Sun.COM
5588480SGirish.Moodalbail@Sun.COM if (argc > 2)
5598275SEric Cheng return (DCMD_USAGE);
5608275SEric Cheng
5618275SEric Cheng if (mdb_vread(&srs, sizeof (srs), addr) == -1) {
5628275SEric Cheng mdb_warn("failed to read struct mac_soft_ring_set_s at %p",
5638275SEric Cheng addr);
5648275SEric Cheng return (DCMD_ERR);
5658275SEric Cheng }
5668480SGirish.Moodalbail@Sun.COM if (mdb_vread(&mci, sizeof (mci), (uintptr_t)srs.srs_mcip) == -1) {
5678480SGirish.Moodalbail@Sun.COM mdb_warn("failed to read struct mac_client_impl_t at %p "
5688480SGirish.Moodalbail@Sun.COM "for SRS %p", srs.srs_mcip, addr);
5698480SGirish.Moodalbail@Sun.COM return (DCMD_ERR);
5708480SGirish.Moodalbail@Sun.COM }
5718275SEric Cheng
5728275SEric Cheng switch (args) {
5738275SEric Cheng case MAC_SRS_RX: {
5748275SEric Cheng if (DCMD_HDRSPEC(flags)) {
5758999SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-8s %-8s %8s "
5768999SGirish.Moodalbail@Sun.COM "%8s %3s\n",
5778480SGirish.Moodalbail@Sun.COM "", "", "", "", "MBLK",
5788480SGirish.Moodalbail@Sun.COM "Q", "SR");
5798999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %-8s %-8s %8s "
5808999SGirish.Moodalbail@Sun.COM "%8s %3s%</u>\n",
5818480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "STATE", "TYPE", "CNT",
5828480SGirish.Moodalbail@Sun.COM "BYTES", "CNT");
5838275SEric Cheng }
5848275SEric Cheng if (srs.srs_type & SRST_TX)
5858275SEric Cheng return (DCMD_OK);
5868480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %08x %08x "
5878999SGirish.Moodalbail@Sun.COM "%8d %8d %3d\n",
5888480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, srs.srs_state, srs.srs_type,
5898480SGirish.Moodalbail@Sun.COM srs.srs_count, srs.srs_size, srs.srs_soft_ring_count);
5908275SEric Cheng break;
5918275SEric Cheng }
5928275SEric Cheng case MAC_SRS_TX: {
5938275SEric Cheng if (DCMD_HDRSPEC(flags)) {
5948480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-16s %-4s %-8s "
5958999SGirish.Moodalbail@Sun.COM "%-8s %8s %8s %3s\n",
5968480SGirish.Moodalbail@Sun.COM "", "", "TX", "",
5978480SGirish.Moodalbail@Sun.COM "", "MBLK", "Q", "SR");
5988480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-16s %-4s %-8s "
5998999SGirish.Moodalbail@Sun.COM "%-8s %8s %8s %3s%</u>\n",
6008480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "MODE", "STATE",
6018480SGirish.Moodalbail@Sun.COM "TYPE", "CNT", "BYTES", "CNT");
6028275SEric Cheng }
6038275SEric Cheng if (!(srs.srs_type & SRST_TX))
6048275SEric Cheng return (DCMD_OK);
6058275SEric Cheng
6068480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-16s %-4s "
6078999SGirish.Moodalbail@Sun.COM "%08x %08x %8d %8d %3d\n",
6088480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, mac_srs_txmode2str(srs.srs_tx.st_mode),
6098480SGirish.Moodalbail@Sun.COM srs.srs_state, srs.srs_type, srs.srs_count, srs.srs_size,
610*11878SVenu.Iyer@Sun.COM srs.srs_tx_ring_count);
6118480SGirish.Moodalbail@Sun.COM break;
6128480SGirish.Moodalbail@Sun.COM }
6138480SGirish.Moodalbail@Sun.COM case MAC_SRS_RXCPU: {
6148480SGirish.Moodalbail@Sun.COM mac_cpus_t mc = srs.srs_cpu;
6158480SGirish.Moodalbail@Sun.COM
6168480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) {
6178480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-4s %-4s "
6188480SGirish.Moodalbail@Sun.COM "%-6s %-4s %-7s\n",
6198480SGirish.Moodalbail@Sun.COM "", "", "NUM", "POLL",
6208480SGirish.Moodalbail@Sun.COM "WORKER", "INTR", "FANOUT");
6218480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %-4s %-4s "
6228480SGirish.Moodalbail@Sun.COM "%-6s %-4s %-7s%</u>\n",
6238480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "CPUS", "CPU",
6248480SGirish.Moodalbail@Sun.COM "CPU", "CPU", "CPU_CNT");
6258480SGirish.Moodalbail@Sun.COM }
6268480SGirish.Moodalbail@Sun.COM if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))
6278480SGirish.Moodalbail@Sun.COM return (DCMD_OK);
6288480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %-4d %-4d "
6298480SGirish.Moodalbail@Sun.COM "%-6d %-4d %-7d\n",
630*11878SVenu.Iyer@Sun.COM addr, mci.mci_name, mc.mc_ncpus, mc.mc_rx_pollid,
631*11878SVenu.Iyer@Sun.COM mc.mc_rx_workerid, mc.mc_rx_intr_cpu, mc.mc_rx_fanout_cnt);
6328480SGirish.Moodalbail@Sun.COM break;
6338480SGirish.Moodalbail@Sun.COM
6348480SGirish.Moodalbail@Sun.COM }
6358480SGirish.Moodalbail@Sun.COM case MAC_SRS_TXCPU: {
6368480SGirish.Moodalbail@Sun.COM mac_cpus_t mc = srs.srs_cpu;
637*11878SVenu.Iyer@Sun.COM mac_soft_ring_t *s_ringp, s_ring;
638*11878SVenu.Iyer@Sun.COM boolean_t first = B_TRUE;
639*11878SVenu.Iyer@Sun.COM int i;
640*11878SVenu.Iyer@Sun.COM
641*11878SVenu.Iyer@Sun.COM if (DCMD_HDRSPEC(flags)) {
642*11878SVenu.Iyer@Sun.COM mdb_printf("%?s %-12s %?s %8s %8s %8s\n",
643*11878SVenu.Iyer@Sun.COM "", "", "SOFT", "WORKER", "INTR", "RETARGETED");
644*11878SVenu.Iyer@Sun.COM mdb_printf("%<u>%?s %-12s %?s %8s %8s %8s%</u>\n",
645*11878SVenu.Iyer@Sun.COM "ADDR", "LINK_NAME", "RING", "CPU", "CPU", "CPU");
646*11878SVenu.Iyer@Sun.COM }
647*11878SVenu.Iyer@Sun.COM if (!(srs.srs_type & SRST_TX))
648*11878SVenu.Iyer@Sun.COM return (DCMD_OK);
649*11878SVenu.Iyer@Sun.COM
650*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %-12s ", addr, mci.mci_name);
651*11878SVenu.Iyer@Sun.COM
652*11878SVenu.Iyer@Sun.COM /*
653*11878SVenu.Iyer@Sun.COM * Case of no soft rings, print the info from
654*11878SVenu.Iyer@Sun.COM * mac_srs_tx_t.
655*11878SVenu.Iyer@Sun.COM */
656*11878SVenu.Iyer@Sun.COM if (srs.srs_tx_ring_count == 0) {
657*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %8d %8d\n",
658*11878SVenu.Iyer@Sun.COM 0, mc.mc_tx_fanout_cpus[0],
659*11878SVenu.Iyer@Sun.COM mc.mc_tx_intr_cpu[0],
660*11878SVenu.Iyer@Sun.COM mc.mc_tx_retargeted_cpu[0]);
661*11878SVenu.Iyer@Sun.COM break;
662*11878SVenu.Iyer@Sun.COM }
663*11878SVenu.Iyer@Sun.COM
664*11878SVenu.Iyer@Sun.COM for (s_ringp = srs.srs_soft_ring_head, i = 0; s_ringp != NULL;
665*11878SVenu.Iyer@Sun.COM s_ringp = s_ring.s_ring_next, i++) {
666*11878SVenu.Iyer@Sun.COM (void) mdb_vread(&s_ring, sizeof (s_ring),
667*11878SVenu.Iyer@Sun.COM (uintptr_t)s_ringp);
668*11878SVenu.Iyer@Sun.COM if (first) {
669*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %8d %8d\n",
670*11878SVenu.Iyer@Sun.COM s_ringp, mc.mc_tx_fanout_cpus[i],
671*11878SVenu.Iyer@Sun.COM mc.mc_tx_intr_cpu[i],
672*11878SVenu.Iyer@Sun.COM mc.mc_tx_retargeted_cpu[i]);
673*11878SVenu.Iyer@Sun.COM first = B_FALSE;
674*11878SVenu.Iyer@Sun.COM continue;
675*11878SVenu.Iyer@Sun.COM }
676*11878SVenu.Iyer@Sun.COM mdb_printf("%?s %-12s %?p %8d %8d %8d\n",
677*11878SVenu.Iyer@Sun.COM "", "", s_ringp, mc.mc_tx_fanout_cpus[i],
678*11878SVenu.Iyer@Sun.COM mc.mc_tx_intr_cpu[i], mc.mc_tx_retargeted_cpu[i]);
679*11878SVenu.Iyer@Sun.COM }
680*11878SVenu.Iyer@Sun.COM break;
681*11878SVenu.Iyer@Sun.COM }
682*11878SVenu.Iyer@Sun.COM case MAC_SRS_TXINTR: {
683*11878SVenu.Iyer@Sun.COM mac_cpus_t mc = srs.srs_cpu;
684*11878SVenu.Iyer@Sun.COM mac_soft_ring_t *s_ringp, s_ring;
685*11878SVenu.Iyer@Sun.COM mac_ring_t *m_ringp, m_ring;
686*11878SVenu.Iyer@Sun.COM boolean_t first = B_TRUE;
687*11878SVenu.Iyer@Sun.COM int i;
6888480SGirish.Moodalbail@Sun.COM
6898480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) {
690*11878SVenu.Iyer@Sun.COM mdb_printf("%?s %-12s %?s %8s %?s %6s %6s\n",
691*11878SVenu.Iyer@Sun.COM "", "", "SOFT", "WORKER", "MAC", "", "INTR");
692*11878SVenu.Iyer@Sun.COM mdb_printf("%<u>%?s %-12s %?s %8s %?s %6s %6s%</u>\n",
693*11878SVenu.Iyer@Sun.COM "ADDR", "LINK_NAME", "RING", "CPU", "RING",
694*11878SVenu.Iyer@Sun.COM "SHARED", "CPU");
695*11878SVenu.Iyer@Sun.COM }
696*11878SVenu.Iyer@Sun.COM if (!(srs.srs_type & SRST_TX))
697*11878SVenu.Iyer@Sun.COM return (DCMD_OK);
698*11878SVenu.Iyer@Sun.COM
699*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %-12s ", addr, mci.mci_name);
700*11878SVenu.Iyer@Sun.COM
701*11878SVenu.Iyer@Sun.COM /*
702*11878SVenu.Iyer@Sun.COM * Case of no soft rings, print the info from
703*11878SVenu.Iyer@Sun.COM * mac_srs_tx_t.
704*11878SVenu.Iyer@Sun.COM */
705*11878SVenu.Iyer@Sun.COM if (srs.srs_tx_ring_count == 0) {
706*11878SVenu.Iyer@Sun.COM m_ringp = srs.srs_tx.st_arg2;
707*11878SVenu.Iyer@Sun.COM if (m_ringp != NULL) {
708*11878SVenu.Iyer@Sun.COM (void) mdb_vread(&m_ring, sizeof (m_ring),
709*11878SVenu.Iyer@Sun.COM (uintptr_t)m_ringp);
710*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %?p %6d %6d\n",
711*11878SVenu.Iyer@Sun.COM 0, mc.mc_tx_fanout_cpus[0], m_ringp,
712*11878SVenu.Iyer@Sun.COM m_ring.mr_info.mri_intr.mi_ddi_shared,
713*11878SVenu.Iyer@Sun.COM mc.mc_tx_retargeted_cpu[0]);
714*11878SVenu.Iyer@Sun.COM } else {
715*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %?p %6d %6d\n",
716*11878SVenu.Iyer@Sun.COM 0, mc.mc_tx_fanout_cpus[0], 0,
717*11878SVenu.Iyer@Sun.COM 0, mc.mc_tx_retargeted_cpu[0]);
718*11878SVenu.Iyer@Sun.COM }
719*11878SVenu.Iyer@Sun.COM break;
7208480SGirish.Moodalbail@Sun.COM }
721*11878SVenu.Iyer@Sun.COM
722*11878SVenu.Iyer@Sun.COM for (s_ringp = srs.srs_soft_ring_head, i = 0; s_ringp != NULL;
723*11878SVenu.Iyer@Sun.COM s_ringp = s_ring.s_ring_next, i++) {
724*11878SVenu.Iyer@Sun.COM (void) mdb_vread(&s_ring, sizeof (s_ring),
725*11878SVenu.Iyer@Sun.COM (uintptr_t)s_ringp);
726*11878SVenu.Iyer@Sun.COM m_ringp = s_ring.s_ring_tx_arg2;
727*11878SVenu.Iyer@Sun.COM (void) mdb_vread(&m_ring, sizeof (m_ring),
728*11878SVenu.Iyer@Sun.COM (uintptr_t)m_ringp);
729*11878SVenu.Iyer@Sun.COM if (first) {
730*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %?p %6d %6d\n",
731*11878SVenu.Iyer@Sun.COM s_ringp, mc.mc_tx_fanout_cpus[i],
732*11878SVenu.Iyer@Sun.COM m_ringp,
733*11878SVenu.Iyer@Sun.COM m_ring.mr_info.mri_intr.mi_ddi_shared,
734*11878SVenu.Iyer@Sun.COM mc.mc_tx_retargeted_cpu[i]);
735*11878SVenu.Iyer@Sun.COM first = B_FALSE;
736*11878SVenu.Iyer@Sun.COM continue;
737*11878SVenu.Iyer@Sun.COM }
738*11878SVenu.Iyer@Sun.COM mdb_printf("%?s %-12s %?p %8d %?p %6d %6d\n",
739*11878SVenu.Iyer@Sun.COM "", "", s_ringp, mc.mc_tx_fanout_cpus[i],
740*11878SVenu.Iyer@Sun.COM m_ringp, m_ring.mr_info.mri_intr.mi_ddi_shared,
741*11878SVenu.Iyer@Sun.COM mc.mc_tx_retargeted_cpu[i]);
742*11878SVenu.Iyer@Sun.COM }
743*11878SVenu.Iyer@Sun.COM break;
744*11878SVenu.Iyer@Sun.COM }
745*11878SVenu.Iyer@Sun.COM case MAC_SRS_RXINTR: {
746*11878SVenu.Iyer@Sun.COM mac_cpus_t mc = srs.srs_cpu;
747*11878SVenu.Iyer@Sun.COM mac_ring_t *m_ringp, m_ring;
748*11878SVenu.Iyer@Sun.COM
749*11878SVenu.Iyer@Sun.COM if (DCMD_HDRSPEC(flags)) {
750*11878SVenu.Iyer@Sun.COM mdb_printf("%?s %-12s %?s %8s %6s %6s\n",
751*11878SVenu.Iyer@Sun.COM "", "", "MAC", "", "POLL", "INTR");
752*11878SVenu.Iyer@Sun.COM mdb_printf("%<u>%?s %-12s %?s %8s %6s %6s%</u>\n",
753*11878SVenu.Iyer@Sun.COM "ADDR", "LINK_NAME", "RING", "SHARED", "CPU",
754*11878SVenu.Iyer@Sun.COM "CPU");
755*11878SVenu.Iyer@Sun.COM }
756*11878SVenu.Iyer@Sun.COM if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))
7578480SGirish.Moodalbail@Sun.COM return (DCMD_OK);
758*11878SVenu.Iyer@Sun.COM
759*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %-12s ", addr, mci.mci_name);
760*11878SVenu.Iyer@Sun.COM
761*11878SVenu.Iyer@Sun.COM m_ringp = srs.srs_ring;
762*11878SVenu.Iyer@Sun.COM if (m_ringp != NULL) {
763*11878SVenu.Iyer@Sun.COM (void) mdb_vread(&m_ring, sizeof (m_ring),
764*11878SVenu.Iyer@Sun.COM (uintptr_t)m_ringp);
765*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %6d %6d\n",
766*11878SVenu.Iyer@Sun.COM m_ringp, m_ring.mr_info.mri_intr.mi_ddi_shared,
767*11878SVenu.Iyer@Sun.COM mc.mc_rx_pollid, mc.mc_rx_intr_cpu);
768*11878SVenu.Iyer@Sun.COM } else {
769*11878SVenu.Iyer@Sun.COM mdb_printf("%?p %8d %6d %6d\n",
770*11878SVenu.Iyer@Sun.COM 0, 0, mc.mc_rx_pollid, mc.mc_rx_intr_cpu);
771*11878SVenu.Iyer@Sun.COM }
7728275SEric Cheng break;
7738275SEric Cheng }
7748480SGirish.Moodalbail@Sun.COM case MAC_SRS_RXCPUVERBOSE:
7758480SGirish.Moodalbail@Sun.COM case MAC_SRS_TXCPUVERBOSE: {
7768480SGirish.Moodalbail@Sun.COM mac_cpus_t mc = srs.srs_cpu;
7778480SGirish.Moodalbail@Sun.COM int cpu_index = 0, fanout_index = 0, len = 0;
7788480SGirish.Moodalbail@Sun.COM boolean_t cpu_done = B_FALSE, fanout_done = B_FALSE;
7798480SGirish.Moodalbail@Sun.COM
7808275SEric Cheng if (DCMD_HDRSPEC(flags)) {
7818480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %-20s %-20s\n",
7828480SGirish.Moodalbail@Sun.COM "", "", "CPU_COUNT", "FANOUT_CPU_COUNT");
7838480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s "
7848480SGirish.Moodalbail@Sun.COM "%-20s %-20s%</u>\n",
7858480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME",
7868480SGirish.Moodalbail@Sun.COM "(CPU_LIST)", "(CPU_LIST)");
7878275SEric Cheng }
7888480SGirish.Moodalbail@Sun.COM if (((args & MAC_SRS_TX) && !(srs.srs_type & SRST_TX)) ||
7898480SGirish.Moodalbail@Sun.COM ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX)))
7908480SGirish.Moodalbail@Sun.COM return (DCMD_OK);
7918480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %-20d %-20d\n", addr, mci.mci_name,
792*11878SVenu.Iyer@Sun.COM mc.mc_ncpus, mc.mc_rx_fanout_cnt);
793*11878SVenu.Iyer@Sun.COM if (mc.mc_ncpus == 0 && mc.mc_rx_fanout_cnt == 0)
7948480SGirish.Moodalbail@Sun.COM break;
7958480SGirish.Moodalbail@Sun.COM /* print all cpus and cpus for soft rings */
7968480SGirish.Moodalbail@Sun.COM while (!cpu_done || !fanout_done) {
7978480SGirish.Moodalbail@Sun.COM boolean_t old_value = cpu_done;
7988480SGirish.Moodalbail@Sun.COM
7998480SGirish.Moodalbail@Sun.COM if (!cpu_done) {
8008480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %20s ", "", "");
8018480SGirish.Moodalbail@Sun.COM cpu_done = mac_srs_print_cpu(&cpu_index,
8028480SGirish.Moodalbail@Sun.COM mc.mc_ncpus, mc.mc_cpus, &len);
8038480SGirish.Moodalbail@Sun.COM }
8048480SGirish.Moodalbail@Sun.COM if (!fanout_done) {
8058480SGirish.Moodalbail@Sun.COM if (old_value)
8068480SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-40s", "", "");
8078480SGirish.Moodalbail@Sun.COM else
8088480SGirish.Moodalbail@Sun.COM mdb_printf("%*s", len, "");
8098480SGirish.Moodalbail@Sun.COM fanout_done = mac_srs_print_cpu(&fanout_index,
810*11878SVenu.Iyer@Sun.COM mc.mc_rx_fanout_cnt,
811*11878SVenu.Iyer@Sun.COM mc.mc_rx_fanout_cpus, NULL);
8128480SGirish.Moodalbail@Sun.COM }
8138480SGirish.Moodalbail@Sun.COM mdb_printf("\n");
8148480SGirish.Moodalbail@Sun.COM }
8158275SEric Cheng break;
8168275SEric Cheng }
8178480SGirish.Moodalbail@Sun.COM case MAC_SRS_RXSTAT: {
818*11878SVenu.Iyer@Sun.COM mac_rx_stats_t *mac_rx_stat = &srs.srs_rx.sr_stat;
8198480SGirish.Moodalbail@Sun.COM
8208480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) {
8218999SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-16s %8s %8s "
8228999SGirish.Moodalbail@Sun.COM "%8s %8s %8s\n",
8238480SGirish.Moodalbail@Sun.COM "", "", "INTR", "POLL",
8248480SGirish.Moodalbail@Sun.COM "CHAIN", "CHAIN", "CHAIN");
8258999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-16s %8s %8s "
8268999SGirish.Moodalbail@Sun.COM "%8s %8s %8s%</u>\n",
8278480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "COUNT", "COUNT",
8288480SGirish.Moodalbail@Sun.COM "<10", "10-50", ">50");
8298480SGirish.Moodalbail@Sun.COM }
8308480SGirish.Moodalbail@Sun.COM if (srs.srs_type & SRST_TX)
8318480SGirish.Moodalbail@Sun.COM return (DCMD_OK);
8328999SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-16s %8d "
8338999SGirish.Moodalbail@Sun.COM "%8d %8d "
8348999SGirish.Moodalbail@Sun.COM "%8d %8d\n",
835*11878SVenu.Iyer@Sun.COM addr, mci.mci_name, mac_rx_stat->mrs_intrcnt,
836*11878SVenu.Iyer@Sun.COM mac_rx_stat->mrs_pollcnt, mac_rx_stat->mrs_chaincntundr10,
837*11878SVenu.Iyer@Sun.COM mac_rx_stat->mrs_chaincnt10to50,
838*11878SVenu.Iyer@Sun.COM mac_rx_stat->mrs_chaincntover50);
8398480SGirish.Moodalbail@Sun.COM break;
8408480SGirish.Moodalbail@Sun.COM }
8418480SGirish.Moodalbail@Sun.COM case MAC_SRS_TXSTAT: {
842*11878SVenu.Iyer@Sun.COM mac_tx_stats_t *mac_tx_stat = &srs.srs_tx.st_stat;
8438999SGirish.Moodalbail@Sun.COM mac_soft_ring_t *s_ringp, s_ring;
8448999SGirish.Moodalbail@Sun.COM boolean_t first = B_TRUE;
8458480SGirish.Moodalbail@Sun.COM
8468480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) {
8478999SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %?s %8s %8s %8s\n",
8488999SGirish.Moodalbail@Sun.COM "", "", "SOFT", "DROP", "BLOCK", "UNBLOCK");
8498999SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %?s %8s %8s %8s%</u>\n",
8508999SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "RING", "COUNT", "COUNT",
8518999SGirish.Moodalbail@Sun.COM "COUNT");
8528480SGirish.Moodalbail@Sun.COM }
8538480SGirish.Moodalbail@Sun.COM if (!(srs.srs_type & SRST_TX))
8548480SGirish.Moodalbail@Sun.COM return (DCMD_OK);
8558480SGirish.Moodalbail@Sun.COM
8568999SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s ", addr, mci.mci_name);
8578999SGirish.Moodalbail@Sun.COM
8588999SGirish.Moodalbail@Sun.COM /*
8598999SGirish.Moodalbail@Sun.COM * Case of no soft rings, print the info from
8608999SGirish.Moodalbail@Sun.COM * mac_srs_tx_t.
8618999SGirish.Moodalbail@Sun.COM */
862*11878SVenu.Iyer@Sun.COM if (srs.srs_tx_ring_count == 0) {
8638999SGirish.Moodalbail@Sun.COM mdb_printf("%?p %8d %8d %8d\n",
864*11878SVenu.Iyer@Sun.COM 0, mac_tx_stat->mts_sdrops,
865*11878SVenu.Iyer@Sun.COM mac_tx_stat->mts_blockcnt,
866*11878SVenu.Iyer@Sun.COM mac_tx_stat->mts_unblockcnt);
8678999SGirish.Moodalbail@Sun.COM break;
8688999SGirish.Moodalbail@Sun.COM }
8698999SGirish.Moodalbail@Sun.COM
8708999SGirish.Moodalbail@Sun.COM for (s_ringp = srs.srs_soft_ring_head; s_ringp != NULL;
8718999SGirish.Moodalbail@Sun.COM s_ringp = s_ring.s_ring_next) {
8728999SGirish.Moodalbail@Sun.COM (void) mdb_vread(&s_ring, sizeof (s_ring),
8738999SGirish.Moodalbail@Sun.COM (uintptr_t)s_ringp);
874*11878SVenu.Iyer@Sun.COM mac_tx_stat = &s_ring.s_st_stat;
8758999SGirish.Moodalbail@Sun.COM if (first) {
8768999SGirish.Moodalbail@Sun.COM mdb_printf("%?p %8d %8d %8d\n",
877*11878SVenu.Iyer@Sun.COM s_ringp, mac_tx_stat->mts_sdrops,
878*11878SVenu.Iyer@Sun.COM mac_tx_stat->mts_blockcnt,
879*11878SVenu.Iyer@Sun.COM mac_tx_stat->mts_unblockcnt);
8808999SGirish.Moodalbail@Sun.COM first = B_FALSE;
8818999SGirish.Moodalbail@Sun.COM continue;
8828999SGirish.Moodalbail@Sun.COM }
8838999SGirish.Moodalbail@Sun.COM mdb_printf("%?s %-20s %?p %8d %8d %8d\n",
884*11878SVenu.Iyer@Sun.COM "", "", s_ringp, mac_tx_stat->mts_sdrops,
885*11878SVenu.Iyer@Sun.COM mac_tx_stat->mts_blockcnt,
886*11878SVenu.Iyer@Sun.COM mac_tx_stat->mts_unblockcnt);
8878999SGirish.Moodalbail@Sun.COM }
8888480SGirish.Moodalbail@Sun.COM break;
8898480SGirish.Moodalbail@Sun.COM }
8908480SGirish.Moodalbail@Sun.COM case MAC_SRS_NONE: {
8918480SGirish.Moodalbail@Sun.COM if (DCMD_HDRSPEC(flags)) {
8928480SGirish.Moodalbail@Sun.COM mdb_printf("%<u>%?s %-20s %?s %?s %-3s%</u>\n",
8938480SGirish.Moodalbail@Sun.COM "ADDR", "LINK_NAME", "FLENT", "HW RING", "DIR");
8948480SGirish.Moodalbail@Sun.COM }
8958480SGirish.Moodalbail@Sun.COM mdb_printf("%?p %-20s %?p %?p "
8968480SGirish.Moodalbail@Sun.COM "%-3s ",
8978480SGirish.Moodalbail@Sun.COM addr, mci.mci_name, srs.srs_flent, srs.srs_ring,
8988480SGirish.Moodalbail@Sun.COM (srs.srs_type & SRST_TX ? "TX" : "RX"));
8998480SGirish.Moodalbail@Sun.COM break;
9008480SGirish.Moodalbail@Sun.COM }
9018480SGirish.Moodalbail@Sun.COM default:
9028480SGirish.Moodalbail@Sun.COM return (DCMD_USAGE);
9038275SEric Cheng }
9048275SEric Cheng return (DCMD_OK);
9058275SEric Cheng }
9068275SEric Cheng
9078275SEric Cheng static int
mac_srs_walk_init(mdb_walk_state_t * wsp)9088275SEric Cheng mac_srs_walk_init(mdb_walk_state_t *wsp)
9098275SEric Cheng {
9108275SEric Cheng if (mdb_layered_walk(LAYERED_WALKER_FOR_SRS, wsp) == -1) {
9118275SEric Cheng mdb_warn("failed to walk 'mac_srs'");
9128275SEric Cheng return (WALK_ERR);
9138275SEric Cheng }
9148275SEric Cheng return (WALK_NEXT);
9158275SEric Cheng }
9168275SEric Cheng
9178275SEric Cheng static char *
mac_ring_state2str(mac_ring_state_t state)9188275SEric Cheng mac_ring_state2str(mac_ring_state_t state)
9198275SEric Cheng {
9208275SEric Cheng switch (state) {
9218275SEric Cheng case MR_FREE:
9228275SEric Cheng return ("free");
9238275SEric Cheng case MR_NEWLY_ADDED:
9248275SEric Cheng return ("new");
9258275SEric Cheng case MR_INUSE:
9268275SEric Cheng return ("inuse");
9278275SEric Cheng }
9288275SEric Cheng return ("--");
9298275SEric Cheng }
9308275SEric Cheng
9318275SEric Cheng static char *
mac_ring_classify2str(mac_classify_type_t classify)9328275SEric Cheng mac_ring_classify2str(mac_classify_type_t classify)
9338275SEric Cheng {
9348275SEric Cheng switch (classify) {
9358275SEric Cheng case MAC_NO_CLASSIFIER:
9368275SEric Cheng return ("no");
9378275SEric Cheng case MAC_SW_CLASSIFIER:
9388275SEric Cheng return ("sw");
9398275SEric Cheng case MAC_HW_CLASSIFIER:
9408275SEric Cheng return ("hw");
9418275SEric Cheng }
9428275SEric Cheng return ("--");
9438275SEric Cheng }
9448275SEric Cheng
9458275SEric Cheng static int
mac_ring_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)9468275SEric Cheng mac_ring_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
9478275SEric Cheng {
9488275SEric Cheng mac_ring_t ring;
9498275SEric Cheng mac_group_t group;
9508275SEric Cheng flow_entry_t flent;
9518275SEric Cheng mac_soft_ring_set_t srs;
9528275SEric Cheng
9538275SEric Cheng if (!(flags & DCMD_ADDRSPEC)) {
9548275SEric Cheng if (mdb_walk_dcmd("mac_ring", "mac_ring", argc, argv) == -1) {
9558275SEric Cheng mdb_warn("failed to walk 'mac_ring'");
9568275SEric Cheng return (DCMD_ERR);
9578275SEric Cheng }
9588275SEric Cheng return (DCMD_OK);
9598275SEric Cheng }
9608275SEric Cheng if (mdb_vread(&ring, sizeof (ring), addr) == -1) {
9618275SEric Cheng mdb_warn("failed to read struct mac_ring_s at %p", addr);
9628275SEric Cheng return (DCMD_ERR);
9638275SEric Cheng }
9648275SEric Cheng bzero(&flent, sizeof (flent));
9658275SEric Cheng if (mdb_vread(&srs, sizeof (srs), (uintptr_t)ring.mr_srs) != -1) {
9668275SEric Cheng (void) mdb_vread(&flent, sizeof (flent),
9678275SEric Cheng (uintptr_t)srs.srs_flent);
9688275SEric Cheng }
9698275SEric Cheng (void) mdb_vread(&group, sizeof (group), (uintptr_t)ring.mr_gh);
9708275SEric Cheng if (DCMD_HDRSPEC(flags)) {
9718275SEric Cheng mdb_printf("%<u>%?s %4s %5s %4s %?s "
9728275SEric Cheng "%5s %?s %?s %s %</u>\n",
9738275SEric Cheng "ADDR", "TYPE", "STATE", "FLAG", "GROUP",
9748275SEric Cheng "CLASS", "MIP", "SRS", "FLOW NAME");
9758275SEric Cheng }
9768275SEric Cheng mdb_printf("%?p %-4s "
9778275SEric Cheng "%5s %04x "
9788275SEric Cheng "%?p %-5s "
9798275SEric Cheng "%?p %?p %s\n",
9808275SEric Cheng addr, ((ring.mr_type == 1)? "RX" : "TX"),
9818275SEric Cheng mac_ring_state2str(ring.mr_state), ring.mr_flag,
9828275SEric Cheng ring.mr_gh, mac_ring_classify2str(ring.mr_classify_type),
9838275SEric Cheng group.mrg_mh, ring.mr_srs, flent.fe_flow_name);
9848275SEric Cheng return (DCMD_OK);
9858275SEric Cheng }
9868275SEric Cheng
9878275SEric Cheng static int
mac_ring_walk_init(mdb_walk_state_t * wsp)9888275SEric Cheng mac_ring_walk_init(mdb_walk_state_t *wsp)
9898275SEric Cheng {
9908275SEric Cheng if (mdb_layered_walk(LAYERED_WALKER_FOR_RING, wsp) == -1) {
9918275SEric Cheng mdb_warn("failed to walk `mac_ring`");
9928275SEric Cheng return (WALK_ERR);
9938275SEric Cheng }
9948275SEric Cheng return (WALK_NEXT);
9958275SEric Cheng }
9968275SEric Cheng
9978275SEric Cheng static void
mac_ring_help(void)9988275SEric Cheng mac_ring_help(void)
9998275SEric Cheng {
10008275SEric Cheng mdb_printf("If an address is specified, then mac_ring_t "
10018275SEric Cheng "structure at that address is printed. Otherwise all the "
10028275SEric Cheng "hardware rings in the system are printed.\n");
10038275SEric Cheng }
10048275SEric Cheng
10058275SEric Cheng /* Supported dee-commands */
10068275SEric Cheng static const mdb_dcmd_t dcmds[] = {
10078275SEric Cheng {"mac_flow", "?[-u] [-aprtsm]", "display Flow Entry structures",
10088275SEric Cheng mac_flow_dcmd, mac_flow_help},
1009*11878SVenu.Iyer@Sun.COM {"mac_srs", "?[ -r[i|s|c[v]] | -t[i|s|c[v]] ]",
1010*11878SVenu.Iyer@Sun.COM "display MAC Soft Ring Set" " structures", mac_srs_dcmd,
1011*11878SVenu.Iyer@Sun.COM mac_srs_help},
10128275SEric Cheng {"mac_ring", "?", "display MAC ring (hardware) structures",
10138275SEric Cheng mac_ring_dcmd, mac_ring_help},
10148275SEric Cheng { NULL }
10158275SEric Cheng };
10168275SEric Cheng
10178275SEric Cheng /* Supported walkers */
10188275SEric Cheng static const mdb_walker_t walkers[] = {
10198275SEric Cheng {"mac_flow", "walk list of flow entry structures", mac_flow_walk_init,
10208275SEric Cheng mac_common_walk_step, NULL, NULL},
10218275SEric Cheng {"mac_srs", "walk list of mac soft ring set structures",
10228275SEric Cheng mac_srs_walk_init, mac_common_walk_step, NULL, NULL},
10238275SEric Cheng {"mac_ring", "walk list of mac ring structures", mac_ring_walk_init,
10248275SEric Cheng mac_common_walk_step, NULL, NULL},
10258275SEric Cheng { NULL }
10268275SEric Cheng };
10278275SEric Cheng
10288275SEric Cheng static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
10298275SEric Cheng
10308275SEric Cheng const mdb_modinfo_t *
_mdb_init(void)10318275SEric Cheng _mdb_init(void)
10328275SEric Cheng {
10338275SEric Cheng return (&modinfo);
10348275SEric Cheng }
1035