xref: /illumos-gate/usr/src/cmd/mdb/common/modules/mac/mac.c (revision 45948e49)
1da14cebeSEric Cheng /*
2da14cebeSEric Cheng  * CDDL HEADER START
3da14cebeSEric Cheng  *
4da14cebeSEric Cheng  * The contents of this file are subject to the terms of the
5da14cebeSEric Cheng  * Common Development and Distribution License (the "License").
6da14cebeSEric Cheng  * You may not use this file except in compliance with the License.
7da14cebeSEric Cheng  *
8da14cebeSEric Cheng  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da14cebeSEric Cheng  * or http://www.opensolaris.org/os/licensing.
10da14cebeSEric Cheng  * See the License for the specific language governing permissions
11da14cebeSEric Cheng  * and limitations under the License.
12da14cebeSEric Cheng  *
13da14cebeSEric Cheng  * When distributing Covered Code, include this CDDL HEADER in each
14da14cebeSEric Cheng  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da14cebeSEric Cheng  * If applicable, add the following below this CDDL HEADER, with the
16da14cebeSEric Cheng  * fields enclosed by brackets "[]" replaced with your own identifying
17da14cebeSEric Cheng  * information: Portions Copyright [yyyy] [name of copyright owner]
18da14cebeSEric Cheng  *
19da14cebeSEric Cheng  * CDDL HEADER END
20da14cebeSEric Cheng  */
21da14cebeSEric Cheng /*
220dc2366fSVenugopal Iyer  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23da14cebeSEric Cheng  * Use is subject to license terms.
24*45948e49SRyan Zezeski  * Copyright 2018 Joyent, Inc.
25da14cebeSEric Cheng  */
26da14cebeSEric Cheng 
27da14cebeSEric Cheng #include <sys/mdb_modapi.h>
28da14cebeSEric Cheng #include <sys/types.h>
29da14cebeSEric Cheng #include <inet/ip.h>
30da14cebeSEric Cheng #include <inet/ip6.h>
31da14cebeSEric Cheng 
32da14cebeSEric Cheng #include <sys/mac.h>
33da14cebeSEric Cheng #include <sys/mac_provider.h>
34da14cebeSEric Cheng #include <sys/mac_client.h>
35da14cebeSEric Cheng #include <sys/mac_client_impl.h>
36da14cebeSEric Cheng #include <sys/mac_flow_impl.h>
37da14cebeSEric Cheng #include <sys/mac_soft_ring.h>
380dc2366fSVenugopal Iyer #include <sys/mac_stat.h>
39da14cebeSEric Cheng 
40da14cebeSEric Cheng #define	STRSIZE	64
41da14cebeSEric Cheng #define	MAC_RX_SRS_SIZE	 (MAX_RINGS_PER_GROUP * sizeof (uintptr_t))
42da14cebeSEric Cheng 
43da14cebeSEric Cheng #define	LAYERED_WALKER_FOR_FLOW	"flow_entry_cache"
44da14cebeSEric Cheng #define	LAYERED_WALKER_FOR_SRS	"mac_srs_cache"
45da14cebeSEric Cheng #define	LAYERED_WALKER_FOR_RING	"mac_ring_cache"
46d47ced1fSRobert Mustacchi #define	LAYERED_WALKER_FOR_GROUP	"mac_impl_cache"
47da14cebeSEric Cheng 
48da14cebeSEric Cheng /* arguments passed to mac_flow dee-command */
49da14cebeSEric Cheng #define	MAC_FLOW_NONE	0x01
50da14cebeSEric Cheng #define	MAC_FLOW_ATTR	0x02
51da14cebeSEric Cheng #define	MAC_FLOW_PROP	0x04
52da14cebeSEric Cheng #define	MAC_FLOW_RX	0x08
53da14cebeSEric Cheng #define	MAC_FLOW_TX	0x10
54da14cebeSEric Cheng #define	MAC_FLOW_USER	0x20
55da14cebeSEric Cheng #define	MAC_FLOW_STATS	0x40
56da14cebeSEric Cheng #define	MAC_FLOW_MISC	0x80
57da14cebeSEric Cheng 
58da14cebeSEric Cheng /* arguments passed to mac_srs dee-command */
592ae51e79SGirish Moodalbail #define	MAC_SRS_NONE		0x00
602ae51e79SGirish Moodalbail #define	MAC_SRS_RX		0x01
612ae51e79SGirish Moodalbail #define	MAC_SRS_TX		0x02
622ae51e79SGirish Moodalbail #define	MAC_SRS_STAT		0x04
632ae51e79SGirish Moodalbail #define	MAC_SRS_CPU		0x08
642ae51e79SGirish Moodalbail #define	MAC_SRS_VERBOSE		0x10
650dc2366fSVenugopal Iyer #define	MAC_SRS_INTR		0x20
662ae51e79SGirish Moodalbail #define	MAC_SRS_RXSTAT		(MAC_SRS_RX|MAC_SRS_STAT)
672ae51e79SGirish Moodalbail #define	MAC_SRS_TXSTAT		(MAC_SRS_TX|MAC_SRS_STAT)
682ae51e79SGirish Moodalbail #define	MAC_SRS_RXCPU		(MAC_SRS_RX|MAC_SRS_CPU)
692ae51e79SGirish Moodalbail #define	MAC_SRS_TXCPU		(MAC_SRS_TX|MAC_SRS_CPU)
702ae51e79SGirish Moodalbail #define	MAC_SRS_RXCPUVERBOSE	(MAC_SRS_RXCPU|MAC_SRS_VERBOSE)
712ae51e79SGirish Moodalbail #define	MAC_SRS_TXCPUVERBOSE	(MAC_SRS_TXCPU|MAC_SRS_VERBOSE)
720dc2366fSVenugopal Iyer #define	MAC_SRS_RXINTR		(MAC_SRS_RX|MAC_SRS_INTR)
730dc2366fSVenugopal Iyer #define	MAC_SRS_TXINTR		(MAC_SRS_TX|MAC_SRS_INTR)
74da14cebeSEric Cheng 
75d47ced1fSRobert Mustacchi /* arguments passed to mac_group dcmd */
76d47ced1fSRobert Mustacchi #define	MAC_GROUP_NONE		0x00
77d47ced1fSRobert Mustacchi #define	MAC_GROUP_RX		0x01
78d47ced1fSRobert Mustacchi #define	MAC_GROUP_TX		0x02
79d47ced1fSRobert Mustacchi #define	MAC_GROUP_UNINIT	0x04
80d47ced1fSRobert Mustacchi 
81da14cebeSEric Cheng static char *
mac_flow_proto2str(uint8_t protocol)82da14cebeSEric Cheng mac_flow_proto2str(uint8_t protocol)
83da14cebeSEric Cheng {
84da14cebeSEric Cheng 	switch (protocol) {
85da14cebeSEric Cheng 	case IPPROTO_TCP:
86da14cebeSEric Cheng 		return ("tcp");
87da14cebeSEric Cheng 	case IPPROTO_UDP:
88da14cebeSEric Cheng 		return ("udp");
89da14cebeSEric Cheng 	case IPPROTO_SCTP:
90da14cebeSEric Cheng 		return ("sctp");
91da14cebeSEric Cheng 	case IPPROTO_ICMP:
92da14cebeSEric Cheng 		return ("icmp");
93da14cebeSEric Cheng 	case IPPROTO_ICMPV6:
94da14cebeSEric Cheng 		return ("icmpv6");
95da14cebeSEric Cheng 	default:
96da14cebeSEric Cheng 		return ("--");
97da14cebeSEric Cheng 	}
98da14cebeSEric Cheng }
99da14cebeSEric Cheng 
100da14cebeSEric Cheng static char *
mac_flow_priority2str(mac_priority_level_t prio)101da14cebeSEric Cheng mac_flow_priority2str(mac_priority_level_t prio)
102da14cebeSEric Cheng {
103da14cebeSEric Cheng 	switch (prio) {
104da14cebeSEric Cheng 	case MPL_LOW:
105da14cebeSEric Cheng 		return ("low");
106da14cebeSEric Cheng 	case MPL_MEDIUM:
107da14cebeSEric Cheng 		return ("medium");
108da14cebeSEric Cheng 	case MPL_HIGH:
109da14cebeSEric Cheng 		return ("high");
110da14cebeSEric Cheng 	case MPL_RESET:
111da14cebeSEric Cheng 		return ("reset");
112da14cebeSEric Cheng 	default:
113da14cebeSEric Cheng 		return ("--");
114da14cebeSEric Cheng 	}
115da14cebeSEric Cheng }
116da14cebeSEric Cheng 
117da14cebeSEric Cheng /*
1184a3b1d5bSBart Coddens  *  Convert bandwidth in bps to a string in Mbps.
119da14cebeSEric Cheng  */
120da14cebeSEric Cheng static char *
mac_flow_bw2str(uint64_t bw,char * buf,ssize_t len)121da14cebeSEric Cheng mac_flow_bw2str(uint64_t bw, char *buf, ssize_t len)
122da14cebeSEric Cheng {
123da14cebeSEric Cheng 	int kbps, mbps;
124da14cebeSEric Cheng 
125da14cebeSEric Cheng 	kbps = (bw % 1000000)/1000;
126da14cebeSEric Cheng 	mbps = bw/1000000;
127da14cebeSEric Cheng 	if ((mbps == 0) && (kbps != 0))
128da14cebeSEric Cheng 		mdb_snprintf(buf, len, "0.%03u", kbps);
129da14cebeSEric Cheng 	else
130da14cebeSEric Cheng 		mdb_snprintf(buf, len, "%5u", mbps);
131da14cebeSEric Cheng 	return (buf);
132da14cebeSEric Cheng }
133da14cebeSEric Cheng 
134da14cebeSEric Cheng static void
mac_flow_print_header(uint_t args)135da14cebeSEric Cheng mac_flow_print_header(uint_t args)
136da14cebeSEric Cheng {
137da14cebeSEric Cheng 	switch (args) {
138da14cebeSEric Cheng 	case MAC_FLOW_NONE:
139fcff38ebSGirish Moodalbail 		mdb_printf("%?s %-20s %4s %?s %?s %-16s\n",
140fcff38ebSGirish Moodalbail 		    "", "", "LINK", "", "", "MIP");
141fcff38ebSGirish Moodalbail 		mdb_printf("%<u>%?s %-20s %4s %?s %?s %-16s%</u>\n",
142fcff38ebSGirish Moodalbail 		    "ADDR", "FLOW NAME", "ID", "MCIP", "MIP", "NAME");
143da14cebeSEric Cheng 		break;
144da14cebeSEric Cheng 	case MAC_FLOW_ATTR:
145da14cebeSEric Cheng 		mdb_printf("%<u>%?s %-32s %-7s %6s "
146da14cebeSEric Cheng 		    "%-9s %s%</u>\n",
147da14cebeSEric Cheng 		    "ADDR", "FLOW NAME", "PROTO", "PORT",
148da14cebeSEric Cheng 		    "DSFLD:MSK", "IPADDR");
149da14cebeSEric Cheng 		break;
150da14cebeSEric Cheng 	case MAC_FLOW_PROP:
151da14cebeSEric Cheng 		mdb_printf("%<u>%?s %-32s %8s %9s%</u>\n",
152da14cebeSEric Cheng 		    "ADDR", "FLOW NAME", "MAXBW(M)", "PRIORITY");
153da14cebeSEric Cheng 		break;
154da14cebeSEric Cheng 	case MAC_FLOW_MISC:
155fcff38ebSGirish Moodalbail 		mdb_printf("%<u>%?s %-24s %10s %10s "
156fcff38ebSGirish Moodalbail 		    "%20s %4s%</u>\n",
157da14cebeSEric Cheng 		    "ADDR", "FLOW NAME", "TYPE", "FLAGS",
158da14cebeSEric Cheng 		    "MATCH_FN", "ZONE");
159da14cebeSEric Cheng 		break;
160da14cebeSEric Cheng 	case MAC_FLOW_RX:
161fcff38ebSGirish Moodalbail 		mdb_printf("%?s %-24s %3s %s\n", "", "", "SRS", "RX");
162fcff38ebSGirish Moodalbail 		mdb_printf("%<u>%?s %-24s %3s %s%</u>\n",
163fcff38ebSGirish Moodalbail 		    "ADDR", "FLOW NAME", "CNT", "SRS");
164da14cebeSEric Cheng 		break;
165da14cebeSEric Cheng 	case MAC_FLOW_TX:
166da14cebeSEric Cheng 		mdb_printf("%<u>%?s %-32s %?s %</u>\n",
167da14cebeSEric Cheng 		    "ADDR", "FLOW NAME", "TX_SRS");
168da14cebeSEric Cheng 		break;
169da14cebeSEric Cheng 	case MAC_FLOW_STATS:
170fcff38ebSGirish Moodalbail 		mdb_printf("%<u>%?s %-32s %16s %16s%</u>\n",
171da14cebeSEric Cheng 		    "ADDR", "FLOW NAME", "RBYTES", "OBYTES");
172da14cebeSEric Cheng 		break;
173da14cebeSEric Cheng 	}
174da14cebeSEric Cheng }
175da14cebeSEric Cheng 
176da14cebeSEric Cheng /*
177da14cebeSEric Cheng  * Display selected fields of the flow_entry_t structure
178da14cebeSEric Cheng  */
179da14cebeSEric Cheng static int
mac_flow_dcmd_output(uintptr_t addr,uint_t flags,uint_t args)180da14cebeSEric Cheng mac_flow_dcmd_output(uintptr_t addr, uint_t flags, uint_t args)
181da14cebeSEric Cheng {
182da14cebeSEric Cheng 	static const mdb_bitmask_t flow_type_bits[] = {
183da14cebeSEric Cheng 		{"P", FLOW_PRIMARY_MAC, FLOW_PRIMARY_MAC},
184da14cebeSEric Cheng 		{"V", FLOW_VNIC_MAC, FLOW_VNIC_MAC},
185da14cebeSEric Cheng 		{"M", FLOW_MCAST, FLOW_MCAST},
186da14cebeSEric Cheng 		{"O", FLOW_OTHER, FLOW_OTHER},
187da14cebeSEric Cheng 		{"U", FLOW_USER, FLOW_USER},
188da14cebeSEric Cheng 		{"V", FLOW_VNIC, FLOW_VNIC},
189da14cebeSEric Cheng 		{"NS", FLOW_NO_STATS, FLOW_NO_STATS},
190da14cebeSEric Cheng 		{ NULL, 0, 0 }
191da14cebeSEric Cheng 	};
192da14cebeSEric Cheng #define	FLOW_MAX_TYPE	(sizeof (flow_type_bits) / sizeof (mdb_bitmask_t))
193da14cebeSEric Cheng 
194da14cebeSEric Cheng 	static const mdb_bitmask_t flow_flag_bits[] = {
195da14cebeSEric Cheng 		{"Q", FE_QUIESCE, FE_QUIESCE},
196da14cebeSEric Cheng 		{"W", FE_WAITER, FE_WAITER},
197da14cebeSEric Cheng 		{"T", FE_FLOW_TAB, FE_FLOW_TAB},
198da14cebeSEric Cheng 		{"G", FE_G_FLOW_HASH, FE_G_FLOW_HASH},
199da14cebeSEric Cheng 		{"I", FE_INCIPIENT, FE_INCIPIENT},
200da14cebeSEric Cheng 		{"C", FE_CONDEMNED, FE_CONDEMNED},
201da14cebeSEric Cheng 		{"NU", FE_UF_NO_DATAPATH, FE_UF_NO_DATAPATH},
202da14cebeSEric Cheng 		{"NC", FE_MC_NO_DATAPATH, FE_MC_NO_DATAPATH},
203da14cebeSEric Cheng 		{ NULL, 0, 0 }
204da14cebeSEric Cheng 	};
205da14cebeSEric Cheng #define	FLOW_MAX_FLAGS	(sizeof (flow_flag_bits) / sizeof (mdb_bitmask_t))
206da14cebeSEric Cheng 	flow_entry_t		fe;
207da14cebeSEric Cheng 	mac_client_impl_t	mcip;
208da14cebeSEric Cheng 	mac_impl_t		mip;
209da14cebeSEric Cheng 
210da14cebeSEric Cheng 	if (mdb_vread(&fe, sizeof (fe), addr) == -1) {
211da14cebeSEric Cheng 		mdb_warn("failed to read struct flow_entry_s at %p", addr);
212da14cebeSEric Cheng 		return (DCMD_ERR);
213da14cebeSEric Cheng 	}
214da14cebeSEric Cheng 	if (args & MAC_FLOW_USER) {
215da14cebeSEric Cheng 		args &= ~MAC_FLOW_USER;
216da14cebeSEric Cheng 		if (fe.fe_type & FLOW_MCAST) {
217da14cebeSEric Cheng 			if (DCMD_HDRSPEC(flags))
218da14cebeSEric Cheng 				mac_flow_print_header(args);
219da14cebeSEric Cheng 			return (DCMD_OK);
220da14cebeSEric Cheng 		}
221da14cebeSEric Cheng 	}
222da14cebeSEric Cheng 	if (DCMD_HDRSPEC(flags))
223da14cebeSEric Cheng 		mac_flow_print_header(args);
224da14cebeSEric Cheng 	bzero(&mcip, sizeof (mcip));
225da14cebeSEric Cheng 	bzero(&mip, sizeof (mip));
226da14cebeSEric Cheng 	if (fe.fe_mcip != NULL && mdb_vread(&mcip, sizeof (mcip),
227da14cebeSEric Cheng 	    (uintptr_t)fe.fe_mcip) == sizeof (mcip)) {
228da14cebeSEric Cheng 		(void) mdb_vread(&mip, sizeof (mip), (uintptr_t)mcip.mci_mip);
229da14cebeSEric Cheng 	}
230da14cebeSEric Cheng 	switch (args) {
231da14cebeSEric Cheng 	case MAC_FLOW_NONE: {
232fcff38ebSGirish Moodalbail 		mdb_printf("%?p %-20s %4d %?p "
233fcff38ebSGirish Moodalbail 		    "%?p %-16s\n",
234da14cebeSEric Cheng 		    addr, fe.fe_flow_name, fe.fe_link_id, fe.fe_mcip,
235da14cebeSEric Cheng 		    mcip.mci_mip, mip.mi_name);
236da14cebeSEric Cheng 		break;
237da14cebeSEric Cheng 	}
238da14cebeSEric Cheng 	case MAC_FLOW_ATTR: {
239892ad162SToomas Soome 		struct	in_addr	in4;
240da14cebeSEric Cheng 		uintptr_t	desc_addr;
241da14cebeSEric Cheng 		flow_desc_t	fdesc;
242da14cebeSEric Cheng 
243da14cebeSEric Cheng 		desc_addr = addr + OFFSETOF(flow_entry_t, fe_flow_desc);
244da14cebeSEric Cheng 		if (mdb_vread(&fdesc, sizeof (fdesc), desc_addr) == -1) {
245da14cebeSEric Cheng 			mdb_warn("failed to read struct flow_description at %p",
246da14cebeSEric Cheng 			    desc_addr);
247da14cebeSEric Cheng 			return (DCMD_ERR);
248da14cebeSEric Cheng 		}
249da14cebeSEric Cheng 		mdb_printf("%?p %-32s "
250fcff38ebSGirish Moodalbail 		    "%-7s %6d "
251da14cebeSEric Cheng 		    "%4d:%-4d ",
252da14cebeSEric Cheng 		    addr, fe.fe_flow_name,
253da14cebeSEric Cheng 		    mac_flow_proto2str(fdesc.fd_protocol), fdesc.fd_local_port,
254da14cebeSEric Cheng 		    fdesc.fd_dsfield, fdesc.fd_dsfield_mask);
255da14cebeSEric Cheng 		if (fdesc.fd_ipversion == IPV4_VERSION) {
256da14cebeSEric Cheng 			IN6_V4MAPPED_TO_INADDR(&fdesc.fd_local_addr, &in4);
257da14cebeSEric Cheng 			mdb_printf("%I", in4.s_addr);
258da14cebeSEric Cheng 		} else if (fdesc.fd_ipversion == IPV6_VERSION) {
259da14cebeSEric Cheng 			mdb_printf("%N", &fdesc.fd_local_addr);
260da14cebeSEric Cheng 		} else {
261da14cebeSEric Cheng 			mdb_printf("%s", "--");
262da14cebeSEric Cheng 		}
263da14cebeSEric Cheng 		mdb_printf("\n");
264da14cebeSEric Cheng 		break;
265da14cebeSEric Cheng 	}
266da14cebeSEric Cheng 	case MAC_FLOW_PROP: {
267da14cebeSEric Cheng 		uintptr_t	prop_addr;
268da14cebeSEric Cheng 		char		bwstr[STRSIZE];
269da14cebeSEric Cheng 		mac_resource_props_t	fprop;
270da14cebeSEric Cheng 
271da14cebeSEric Cheng 		prop_addr = addr + OFFSETOF(flow_entry_t, fe_resource_props);
272da14cebeSEric Cheng 		if (mdb_vread(&fprop, sizeof (fprop), prop_addr) == -1) {
273da14cebeSEric Cheng 			mdb_warn("failed to read struct mac_resoource_props "
274da14cebeSEric Cheng 			    "at %p", prop_addr);
275da14cebeSEric Cheng 			return (DCMD_ERR);
276da14cebeSEric Cheng 		}
277da14cebeSEric Cheng 		mdb_printf("%?p %-32s "
278da14cebeSEric Cheng 		    "%8s %9s\n",
279da14cebeSEric Cheng 		    addr, fe.fe_flow_name,
280da14cebeSEric Cheng 		    mac_flow_bw2str(fprop.mrp_maxbw, bwstr, STRSIZE),
281da14cebeSEric Cheng 		    mac_flow_priority2str(fprop.mrp_priority));
282da14cebeSEric Cheng 		break;
283da14cebeSEric Cheng 	}
284da14cebeSEric Cheng 	case MAC_FLOW_MISC: {
285da14cebeSEric Cheng 		char		flow_flags[2 * FLOW_MAX_FLAGS];
286da14cebeSEric Cheng 		char		flow_type[2 * FLOW_MAX_TYPE];
287892ad162SToomas Soome 		GElf_Sym	sym;
288da14cebeSEric Cheng 		char		func_name[MDB_SYM_NAMLEN] = "";
289da14cebeSEric Cheng 		uintptr_t	func, match_addr;
290da14cebeSEric Cheng 
291da14cebeSEric Cheng 		match_addr = addr + OFFSETOF(flow_entry_t, fe_match);
292da14cebeSEric Cheng 		(void) mdb_vread(&func, sizeof (func), match_addr);
293da14cebeSEric Cheng 		(void) mdb_lookup_by_addr(func, MDB_SYM_EXACT, func_name,
294da14cebeSEric Cheng 		    MDB_SYM_NAMLEN, &sym);
295da14cebeSEric Cheng 		mdb_snprintf(flow_flags, 2 * FLOW_MAX_FLAGS, "%hb",
296da14cebeSEric Cheng 		    fe.fe_flags, flow_flag_bits);
297da14cebeSEric Cheng 		mdb_snprintf(flow_type, 2 * FLOW_MAX_TYPE, "%hb",
298da14cebeSEric Cheng 		    fe.fe_type, flow_type_bits);
2992b24ab6bSSebastien Roy 		mdb_printf("%?p %-24s %10s %10s %20s\n",
3002b24ab6bSSebastien Roy 		    addr, fe.fe_flow_name, flow_type, flow_flags, func_name);
301da14cebeSEric Cheng 		break;
302da14cebeSEric Cheng 	}
303da14cebeSEric Cheng 	case MAC_FLOW_RX: {
3042ae51e79SGirish Moodalbail 		uintptr_t	rxaddr, rx_srs[MAX_RINGS_PER_GROUP] = {0};
305da14cebeSEric Cheng 		int		i;
306da14cebeSEric Cheng 
307da14cebeSEric Cheng 		rxaddr = addr + OFFSETOF(flow_entry_t, fe_rx_srs);
308da14cebeSEric Cheng 		(void) mdb_vread(rx_srs, MAC_RX_SRS_SIZE, rxaddr);
309fcff38ebSGirish Moodalbail 		mdb_printf("%?p %-24s %3d ",
3102ae51e79SGirish Moodalbail 		    addr, fe.fe_flow_name, fe.fe_rx_srs_cnt);
311da14cebeSEric Cheng 		for (i = 0; i < MAX_RINGS_PER_GROUP; i++) {
312da14cebeSEric Cheng 			if (rx_srs[i] == 0)
313da14cebeSEric Cheng 				continue;
314da14cebeSEric Cheng 			mdb_printf("%p ", rx_srs[i]);
315da14cebeSEric Cheng 		}
316da14cebeSEric Cheng 		mdb_printf("\n");
317da14cebeSEric Cheng 		break;
318da14cebeSEric Cheng 	}
319da14cebeSEric Cheng 	case MAC_FLOW_TX: {
320da14cebeSEric Cheng 		uintptr_t	tx_srs = 0, txaddr;
321da14cebeSEric Cheng 
322da14cebeSEric Cheng 		txaddr = addr + OFFSETOF(flow_entry_t, fe_tx_srs);
323da14cebeSEric Cheng 		(void) mdb_vread(&tx_srs, sizeof (uintptr_t), txaddr);
324da14cebeSEric Cheng 		mdb_printf("%?p %-32s %?p\n",
325da14cebeSEric Cheng 		    addr, fe.fe_flow_name, fe.fe_tx_srs);
326da14cebeSEric Cheng 		break;
327da14cebeSEric Cheng 	}
328da14cebeSEric Cheng 	case MAC_FLOW_STATS: {
329892ad162SToomas Soome 		uint64_t		totibytes = 0;
330892ad162SToomas Soome 		uint64_t		totobytes = 0;
3310dc2366fSVenugopal Iyer 		mac_soft_ring_set_t	*mac_srs;
33278b013d7SRyan Zezeski 		mac_rx_stats_t		mac_rx_stat;
33378b013d7SRyan Zezeski 		mac_tx_stats_t		mac_tx_stat;
3340dc2366fSVenugopal Iyer 		int			i;
3350dc2366fSVenugopal Iyer 
33678b013d7SRyan Zezeski 		/*
33778b013d7SRyan Zezeski 		 * Sum bytes for all Rx SRS.
33878b013d7SRyan Zezeski 		 */
3390dc2366fSVenugopal Iyer 		for (i = 0; i < fe.fe_rx_srs_cnt; i++) {
3400dc2366fSVenugopal Iyer 			mac_srs = (mac_soft_ring_set_t *)(fe.fe_rx_srs[i]);
34178b013d7SRyan Zezeski 			if (mdb_vread(&mac_rx_stat, sizeof (mac_rx_stats_t),
34278b013d7SRyan Zezeski 			    (uintptr_t)&mac_srs->srs_rx.sr_stat) == -1) {
34378b013d7SRyan Zezeski 				mdb_warn("failed to read mac_rx_stats_t at %p",
34478b013d7SRyan Zezeski 				    &mac_srs->srs_rx.sr_stat);
34578b013d7SRyan Zezeski 				return (DCMD_ERR);
34678b013d7SRyan Zezeski 			}
34778b013d7SRyan Zezeski 
34878b013d7SRyan Zezeski 			totibytes += mac_rx_stat.mrs_intrbytes +
34978b013d7SRyan Zezeski 			    mac_rx_stat.mrs_pollbytes +
35078b013d7SRyan Zezeski 			    mac_rx_stat.mrs_lclbytes;
3510dc2366fSVenugopal Iyer 		}
35278b013d7SRyan Zezeski 
35378b013d7SRyan Zezeski 		/*
35478b013d7SRyan Zezeski 		 * Sum bytes for Tx SRS.
35578b013d7SRyan Zezeski 		 */
3560dc2366fSVenugopal Iyer 		mac_srs = (mac_soft_ring_set_t *)(fe.fe_tx_srs);
3570dc2366fSVenugopal Iyer 		if (mac_srs != NULL) {
35878b013d7SRyan Zezeski 			if (mdb_vread(&mac_tx_stat, sizeof (mac_tx_stats_t),
35978b013d7SRyan Zezeski 			    (uintptr_t)&mac_srs->srs_tx.st_stat) == -1) {
36078b013d7SRyan Zezeski 				mdb_warn("failed to read max_tx_stats_t at %p",
36178b013d7SRyan Zezeski 				    &mac_srs->srs_tx.st_stat);
36278b013d7SRyan Zezeski 				return (DCMD_ERR);
36378b013d7SRyan Zezeski 			}
36478b013d7SRyan Zezeski 
36578b013d7SRyan Zezeski 			totobytes = mac_tx_stat.mts_obytes;
3660dc2366fSVenugopal Iyer 		}
36778b013d7SRyan Zezeski 
368da14cebeSEric Cheng 		mdb_printf("%?p %-32s %16llu %16llu\n",
3690dc2366fSVenugopal Iyer 		    addr, fe.fe_flow_name, totibytes, totobytes);
3700dc2366fSVenugopal Iyer 
371da14cebeSEric Cheng 		break;
372da14cebeSEric Cheng 	}
373da14cebeSEric Cheng 	}
374da14cebeSEric Cheng 	return (DCMD_OK);
375da14cebeSEric Cheng }
376da14cebeSEric Cheng 
377da14cebeSEric Cheng /*
378da14cebeSEric Cheng  * Parse the arguments passed to the dcmd and print all or one flow_entry_t
379da14cebeSEric Cheng  * structures
380da14cebeSEric Cheng  */
381da14cebeSEric Cheng static int
mac_flow_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)382da14cebeSEric Cheng mac_flow_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
383da14cebeSEric Cheng {
384da14cebeSEric Cheng 	uint_t	args = 0;
385da14cebeSEric Cheng 
386da14cebeSEric Cheng 	if (!(flags & DCMD_ADDRSPEC)) {
387da14cebeSEric Cheng 		if (mdb_walk_dcmd("mac_flow", "mac_flow", argc, argv) == -1) {
388da14cebeSEric Cheng 			mdb_warn("failed to walk 'mac_flow'");
389da14cebeSEric Cheng 			return (DCMD_ERR);
390da14cebeSEric Cheng 		}
391da14cebeSEric Cheng 		return (DCMD_OK);
392da14cebeSEric Cheng 	}
393da14cebeSEric Cheng 	if ((mdb_getopts(argc, argv,
394da14cebeSEric Cheng 	    'a', MDB_OPT_SETBITS, MAC_FLOW_ATTR, &args,
395da14cebeSEric Cheng 	    'p', MDB_OPT_SETBITS, MAC_FLOW_PROP, &args,
396da14cebeSEric Cheng 	    'm', MDB_OPT_SETBITS, MAC_FLOW_MISC, &args,
397da14cebeSEric Cheng 	    'r', MDB_OPT_SETBITS, MAC_FLOW_RX, &args,
398da14cebeSEric Cheng 	    't', MDB_OPT_SETBITS, MAC_FLOW_TX, &args,
399da14cebeSEric Cheng 	    's', MDB_OPT_SETBITS, MAC_FLOW_STATS, &args,
400d47ced1fSRobert Mustacchi 	    'u', MDB_OPT_SETBITS, MAC_FLOW_USER, &args,
401d47ced1fSRobert Mustacchi 	    NULL) != argc)) {
402da14cebeSEric Cheng 		return (DCMD_USAGE);
403da14cebeSEric Cheng 	}
404da14cebeSEric Cheng 	if (argc > 2 || (argc == 2 && !(args & MAC_FLOW_USER)))
405da14cebeSEric Cheng 		return (DCMD_USAGE);
406da14cebeSEric Cheng 	/*
407da14cebeSEric Cheng 	 * If no arguments was specified or just "-u" was specified then
408da14cebeSEric Cheng 	 * we default to printing basic information of flows.
409da14cebeSEric Cheng 	 */
410da14cebeSEric Cheng 	if (args == 0 || args == MAC_FLOW_USER)
411da14cebeSEric Cheng 		args |= MAC_FLOW_NONE;
412da14cebeSEric Cheng 
413da14cebeSEric Cheng 	return (mac_flow_dcmd_output(addr, flags, args));
414da14cebeSEric Cheng }
415da14cebeSEric Cheng 
416da14cebeSEric Cheng static void
mac_flow_help(void)417da14cebeSEric Cheng mac_flow_help(void)
418da14cebeSEric Cheng {
419da14cebeSEric Cheng 	mdb_printf("If an address is specified, then flow_entry structure at "
420da14cebeSEric Cheng 	    "that address is printed. Otherwise all the flows in the system "
421da14cebeSEric Cheng 	    "are printed.\n");
422da14cebeSEric Cheng 	mdb_printf("Options:\n"
423da14cebeSEric Cheng 	    "\t-u\tdisplay user defined link & vnic flows.\n"
424da14cebeSEric Cheng 	    "\t-a\tdisplay flow attributes\n"
425da14cebeSEric Cheng 	    "\t-p\tdisplay flow properties\n"
426da14cebeSEric Cheng 	    "\t-r\tdisplay rx side information\n"
427da14cebeSEric Cheng 	    "\t-t\tdisplay tx side information\n"
428da14cebeSEric Cheng 	    "\t-s\tdisplay flow statistics\n"
429da14cebeSEric Cheng 	    "\t-m\tdisplay miscellaneous flow information\n\n");
430da14cebeSEric Cheng 	mdb_printf("%<u>Interpreting Flow type and Flow flags output.%</u>\n");
431da14cebeSEric Cheng 	mdb_printf("Flow Types:\n");
432da14cebeSEric Cheng 	mdb_printf("\t  P --> FLOW_PRIMARY_MAC\n");
433da14cebeSEric Cheng 	mdb_printf("\t  V --> FLOW_VNIC_MAC\n");
434da14cebeSEric Cheng 	mdb_printf("\t  M --> FLOW_MCAST\n");
435da14cebeSEric Cheng 	mdb_printf("\t  O --> FLOW_OTHER\n");
436da14cebeSEric Cheng 	mdb_printf("\t  U --> FLOW_USER\n");
437da14cebeSEric Cheng 	mdb_printf("\t NS --> FLOW_NO_STATS\n\n");
438da14cebeSEric Cheng 	mdb_printf("Flow Flags:\n");
439da14cebeSEric Cheng 	mdb_printf("\t  Q --> FE_QUIESCE\n");
440da14cebeSEric Cheng 	mdb_printf("\t  W --> FE_WAITER\n");
441da14cebeSEric Cheng 	mdb_printf("\t  T --> FE_FLOW_TAB\n");
442da14cebeSEric Cheng 	mdb_printf("\t  G --> FE_G_FLOW_HASH\n");
443da14cebeSEric Cheng 	mdb_printf("\t  I --> FE_INCIPIENT\n");
444da14cebeSEric Cheng 	mdb_printf("\t  C --> FE_CONDEMNED\n");
445da14cebeSEric Cheng 	mdb_printf("\t NU --> FE_UF_NO_DATAPATH\n");
446da14cebeSEric Cheng 	mdb_printf("\t NC --> FE_MC_NO_DATAPATH\n");
447da14cebeSEric Cheng }
448da14cebeSEric Cheng 
449da14cebeSEric Cheng /*
450da14cebeSEric Cheng  * called once by the debugger when the mac_flow walk begins.
451da14cebeSEric Cheng  */
452da14cebeSEric Cheng static int
mac_flow_walk_init(mdb_walk_state_t * wsp)453da14cebeSEric Cheng mac_flow_walk_init(mdb_walk_state_t *wsp)
454da14cebeSEric Cheng {
455da14cebeSEric Cheng 	if (mdb_layered_walk(LAYERED_WALKER_FOR_FLOW, wsp) == -1) {
456da14cebeSEric Cheng 		mdb_warn("failed to walk 'mac_flow'");
457da14cebeSEric Cheng 		return (WALK_ERR);
458da14cebeSEric Cheng 	}
459da14cebeSEric Cheng 	return (WALK_NEXT);
460da14cebeSEric Cheng }
461da14cebeSEric Cheng 
462da14cebeSEric Cheng /*
463da14cebeSEric Cheng  * Common walker step funciton for flow_entry_t, mac_soft_ring_set_t and
464da14cebeSEric Cheng  * mac_ring_t.
465da14cebeSEric Cheng  *
466da14cebeSEric Cheng  * Steps through each flow_entry_t and calls the callback function. If the
467da14cebeSEric Cheng  * user executed ::walk mac_flow, it just prints the address or if the user
468da14cebeSEric Cheng  * executed ::mac_flow it displays selected fields of flow_entry_t structure
469da14cebeSEric Cheng  * by calling "mac_flow_dcmd"
470da14cebeSEric Cheng  */
471da14cebeSEric Cheng static int
mac_common_walk_step(mdb_walk_state_t * wsp)472da14cebeSEric Cheng mac_common_walk_step(mdb_walk_state_t *wsp)
473da14cebeSEric Cheng {
474da14cebeSEric Cheng 	int status;
475da14cebeSEric Cheng 
476892ad162SToomas Soome 	if (wsp->walk_addr == 0)
477da14cebeSEric Cheng 		return (WALK_DONE);
478da14cebeSEric Cheng 
479da14cebeSEric Cheng 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
480da14cebeSEric Cheng 	    wsp->walk_cbdata);
481da14cebeSEric Cheng 
482da14cebeSEric Cheng 	return (status);
483da14cebeSEric Cheng }
484da14cebeSEric Cheng 
485da14cebeSEric Cheng static char *
mac_srs_txmode2str(mac_tx_srs_mode_t mode)486da14cebeSEric Cheng mac_srs_txmode2str(mac_tx_srs_mode_t mode)
487da14cebeSEric Cheng {
488da14cebeSEric Cheng 	switch (mode) {
489da14cebeSEric Cheng 	case SRS_TX_DEFAULT:
4902ae51e79SGirish Moodalbail 		return ("DEF");
491da14cebeSEric Cheng 	case SRS_TX_SERIALIZE:
4922ae51e79SGirish Moodalbail 		return ("SER");
493da14cebeSEric Cheng 	case SRS_TX_FANOUT:
4942ae51e79SGirish Moodalbail 		return ("FO");
495da14cebeSEric Cheng 	case SRS_TX_BW:
4962ae51e79SGirish Moodalbail 		return ("BW");
497da14cebeSEric Cheng 	case SRS_TX_BW_FANOUT:
4982ae51e79SGirish Moodalbail 		return ("BWFO");
4990dc2366fSVenugopal Iyer 	case SRS_TX_AGGR:
5000dc2366fSVenugopal Iyer 		return ("AG");
5010dc2366fSVenugopal Iyer 	case SRS_TX_BW_AGGR:
5020dc2366fSVenugopal Iyer 		return ("BWAG");
503da14cebeSEric Cheng 	}
504da14cebeSEric Cheng 	return ("--");
505da14cebeSEric Cheng }
506da14cebeSEric Cheng 
507da14cebeSEric Cheng static void
mac_srs_help(void)508da14cebeSEric Cheng mac_srs_help(void)
509da14cebeSEric Cheng {
510da14cebeSEric Cheng 	mdb_printf("If an address is specified, then mac_soft_ring_set "
511da14cebeSEric Cheng 	    "structure at that address is printed. Otherwise all the "
512da14cebeSEric Cheng 	    "SRS in the system are printed.\n");
513da14cebeSEric Cheng 	mdb_printf("Options:\n"
514da14cebeSEric Cheng 	    "\t-r\tdisplay recieve side SRS structures\n"
5152ae51e79SGirish Moodalbail 	    "\t-t\tdisplay transmit side SRS structures\n"
5162ae51e79SGirish Moodalbail 	    "\t-s\tdisplay statistics for RX or TX side\n"
5172ae51e79SGirish Moodalbail 	    "\t-c\tdisplay CPU binding for RX or TX side\n"
5182ae51e79SGirish Moodalbail 	    "\t-v\tverbose flag for CPU binding to list cpus\n"
5190dc2366fSVenugopal Iyer 	    "\t-i\tdisplay mac_ring_t and interrupt information\n"
5202ae51e79SGirish Moodalbail 	    "Note: use -r or -t (to specify RX or TX side respectively) along "
5212ae51e79SGirish Moodalbail 	    "with -c or -s\n");
5222ae51e79SGirish Moodalbail 	mdb_printf("\n%<u>Interpreting TX Modes%</u>\n");
5232ae51e79SGirish Moodalbail 	mdb_printf("\t DEF --> Default\n");
5242ae51e79SGirish Moodalbail 	mdb_printf("\t SER --> Serialize\n");
5252ae51e79SGirish Moodalbail 	mdb_printf("\t  FO --> Fanout\n");
5262ae51e79SGirish Moodalbail 	mdb_printf("\t  BW --> Bandwidth\n");
5272ae51e79SGirish Moodalbail 	mdb_printf("\tBWFO --> Bandwidth Fanout\n");
5280dc2366fSVenugopal Iyer 	mdb_printf("\t  AG --> Aggr\n");
5290dc2366fSVenugopal Iyer 	mdb_printf("\tBWAG --> Bandwidth Aggr\n");
5302ae51e79SGirish Moodalbail }
5312ae51e79SGirish Moodalbail 
5322ae51e79SGirish Moodalbail /*
5332ae51e79SGirish Moodalbail  * In verbose mode "::mac_srs -rcv or ::mac_srs -tcv", we print the CPUs
5342ae51e79SGirish Moodalbail  * assigned to a link and CPUS assigned to the soft rings.
5352ae51e79SGirish Moodalbail  * 'len' is used for formatting the output and represents the number of
5362ae51e79SGirish Moodalbail  * spaces between CPU list and Fanout CPU list in the output.
5372ae51e79SGirish Moodalbail  */
5382ae51e79SGirish Moodalbail static boolean_t
mac_srs_print_cpu(int * i,uint32_t cnt,uint32_t * cpu_list,int * len)5392ae51e79SGirish Moodalbail mac_srs_print_cpu(int *i, uint32_t cnt, uint32_t *cpu_list, int *len)
5402ae51e79SGirish Moodalbail {
5412ae51e79SGirish Moodalbail 	int		num = 0;
5422ae51e79SGirish Moodalbail 
5432ae51e79SGirish Moodalbail 	if (*i == 0)
5442ae51e79SGirish Moodalbail 		mdb_printf("(");
5452ae51e79SGirish Moodalbail 	else
5462ae51e79SGirish Moodalbail 		mdb_printf(" ");
5472ae51e79SGirish Moodalbail 	while (*i < cnt) {
5482ae51e79SGirish Moodalbail 		/* We print 6 CPU's at a time to keep display within 80 cols */
5492ae51e79SGirish Moodalbail 		if (((num + 1) % 7) == 0) {
5502ae51e79SGirish Moodalbail 			if (len != NULL)
5512ae51e79SGirish Moodalbail 				*len = 2;
5522ae51e79SGirish Moodalbail 			return (B_FALSE);
5532ae51e79SGirish Moodalbail 		}
5542ae51e79SGirish Moodalbail 		mdb_printf("%02x%c", cpu_list[*i], ((*i == cnt - 1)?')':','));
5552ae51e79SGirish Moodalbail 		++*i;
5562ae51e79SGirish Moodalbail 		++num;
5572ae51e79SGirish Moodalbail 	}
5582ae51e79SGirish Moodalbail 	if (len != NULL)
5592ae51e79SGirish Moodalbail 		*len = (7 - num) * 3;
5602ae51e79SGirish Moodalbail 	return (B_TRUE);
561da14cebeSEric Cheng }
562da14cebeSEric Cheng 
563da14cebeSEric Cheng static int
mac_srs_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)564da14cebeSEric Cheng mac_srs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
565da14cebeSEric Cheng {
5662ae51e79SGirish Moodalbail 	uint_t			args = MAC_SRS_NONE;
567da14cebeSEric Cheng 	mac_soft_ring_set_t	srs;
5682ae51e79SGirish Moodalbail 	mac_client_impl_t	mci;
569da14cebeSEric Cheng 
570da14cebeSEric Cheng 	if (!(flags & DCMD_ADDRSPEC)) {
571da14cebeSEric Cheng 		if (mdb_walk_dcmd("mac_srs", "mac_srs", argc, argv) == -1) {
572da14cebeSEric Cheng 			mdb_warn("failed to walk 'mac_srs'");
573da14cebeSEric Cheng 			return (DCMD_ERR);
574da14cebeSEric Cheng 		}
575da14cebeSEric Cheng 		return (DCMD_OK);
576da14cebeSEric Cheng 	}
5772ae51e79SGirish Moodalbail 	if (mdb_getopts(argc, argv,
578da14cebeSEric Cheng 	    'r', MDB_OPT_SETBITS, MAC_SRS_RX, &args,
5792ae51e79SGirish Moodalbail 	    't', MDB_OPT_SETBITS, MAC_SRS_TX, &args,
5802ae51e79SGirish Moodalbail 	    'c', MDB_OPT_SETBITS, MAC_SRS_CPU, &args,
5812ae51e79SGirish Moodalbail 	    'v', MDB_OPT_SETBITS, MAC_SRS_VERBOSE, &args,
5820dc2366fSVenugopal Iyer 	    'i', MDB_OPT_SETBITS, MAC_SRS_INTR, &args,
583d47ced1fSRobert Mustacchi 	    's', MDB_OPT_SETBITS, MAC_SRS_STAT, &args,
584d47ced1fSRobert Mustacchi 	    NULL) != argc) {
585da14cebeSEric Cheng 		return (DCMD_USAGE);
586da14cebeSEric Cheng 	}
5872ae51e79SGirish Moodalbail 
5882ae51e79SGirish Moodalbail 	if (argc > 2)
589da14cebeSEric Cheng 		return (DCMD_USAGE);
590da14cebeSEric Cheng 
591da14cebeSEric Cheng 	if (mdb_vread(&srs, sizeof (srs), addr) == -1) {
592da14cebeSEric Cheng 		mdb_warn("failed to read struct mac_soft_ring_set_s at %p",
593da14cebeSEric Cheng 		    addr);
594da14cebeSEric Cheng 		return (DCMD_ERR);
595da14cebeSEric Cheng 	}
5962ae51e79SGirish Moodalbail 	if (mdb_vread(&mci, sizeof (mci), (uintptr_t)srs.srs_mcip) == -1) {
5972ae51e79SGirish Moodalbail 		mdb_warn("failed to read struct mac_client_impl_t at %p "
5982ae51e79SGirish Moodalbail 		    "for SRS %p", srs.srs_mcip, addr);
5992ae51e79SGirish Moodalbail 		return (DCMD_ERR);
6002ae51e79SGirish Moodalbail 	}
601da14cebeSEric Cheng 
602da14cebeSEric Cheng 	switch (args) {
603da14cebeSEric Cheng 	case MAC_SRS_RX: {
604da14cebeSEric Cheng 		if (DCMD_HDRSPEC(flags)) {
605fcff38ebSGirish Moodalbail 			mdb_printf("%?s %-20s %-8s %-8s %8s "
606fcff38ebSGirish Moodalbail 			    "%8s %3s\n",
6072ae51e79SGirish Moodalbail 			    "", "", "", "", "MBLK",
6082ae51e79SGirish Moodalbail 			    "Q", "SR");
609fcff38ebSGirish Moodalbail 			mdb_printf("%<u>%?s %-20s %-8s %-8s %8s "
610fcff38ebSGirish Moodalbail 			    "%8s %3s%</u>\n",
6112ae51e79SGirish Moodalbail 			    "ADDR", "LINK_NAME", "STATE", "TYPE", "CNT",
6122ae51e79SGirish Moodalbail 			    "BYTES", "CNT");
613da14cebeSEric Cheng 		}
614da14cebeSEric Cheng 		if (srs.srs_type & SRST_TX)
615da14cebeSEric Cheng 			return (DCMD_OK);
6162ae51e79SGirish Moodalbail 		mdb_printf("%?p %-20s %08x %08x "
617fcff38ebSGirish Moodalbail 		    "%8d %8d %3d\n",
6182ae51e79SGirish Moodalbail 		    addr, mci.mci_name, srs.srs_state, srs.srs_type,
6192ae51e79SGirish Moodalbail 		    srs.srs_count, srs.srs_size, srs.srs_soft_ring_count);
620da14cebeSEric Cheng 		break;
621da14cebeSEric Cheng 	}
622da14cebeSEric Cheng 	case MAC_SRS_TX: {
623da14cebeSEric Cheng 		if (DCMD_HDRSPEC(flags)) {
6242ae51e79SGirish Moodalbail 			mdb_printf("%?s %-16s %-4s %-8s "
625fcff38ebSGirish Moodalbail 			    "%-8s %8s %8s %3s\n",
6262ae51e79SGirish Moodalbail 			    "", "", "TX", "",
6272ae51e79SGirish Moodalbail 			    "", "MBLK", "Q", "SR");
6282ae51e79SGirish Moodalbail 			mdb_printf("%<u>%?s %-16s %-4s %-8s "
629fcff38ebSGirish Moodalbail 			    "%-8s %8s %8s %3s%</u>\n",
6302ae51e79SGirish Moodalbail 			    "ADDR", "LINK_NAME", "MODE", "STATE",
6312ae51e79SGirish Moodalbail 			    "TYPE", "CNT", "BYTES", "CNT");
6322ae51e79SGirish Moodalbail 		}
6332ae51e79SGirish Moodalbail 		if (!(srs.srs_type & SRST_TX))
6342ae51e79SGirish Moodalbail 			return (DCMD_OK);
6352ae51e79SGirish Moodalbail 
6362ae51e79SGirish Moodalbail 		mdb_printf("%?p %-16s %-4s "
637fcff38ebSGirish Moodalbail 		    "%08x %08x %8d %8d %3d\n",
6382ae51e79SGirish Moodalbail 		    addr, mci.mci_name, mac_srs_txmode2str(srs.srs_tx.st_mode),
6392ae51e79SGirish Moodalbail 		    srs.srs_state, srs.srs_type, srs.srs_count, srs.srs_size,
6400dc2366fSVenugopal Iyer 		    srs.srs_tx_ring_count);
6412ae51e79SGirish Moodalbail 		break;
6422ae51e79SGirish Moodalbail 	}
6432ae51e79SGirish Moodalbail 	case MAC_SRS_RXCPU: {
6442ae51e79SGirish Moodalbail 		mac_cpus_t	mc = srs.srs_cpu;
6452ae51e79SGirish Moodalbail 
6462ae51e79SGirish Moodalbail 		if (DCMD_HDRSPEC(flags)) {
6472ae51e79SGirish Moodalbail 			mdb_printf("%?s %-20s %-4s %-4s "
6482ae51e79SGirish Moodalbail 			    "%-6s %-4s %-7s\n",
6492ae51e79SGirish Moodalbail 			    "", "", "NUM", "POLL",
6502ae51e79SGirish Moodalbail 			    "WORKER", "INTR", "FANOUT");
6512ae51e79SGirish Moodalbail 			mdb_printf("%<u>%?s %-20s %-4s %-4s "
6522ae51e79SGirish Moodalbail 			    "%-6s %-4s %-7s%</u>\n",
6532ae51e79SGirish Moodalbail 			    "ADDR", "LINK_NAME", "CPUS", "CPU",
6542ae51e79SGirish Moodalbail 			    "CPU", "CPU", "CPU_CNT");
6552ae51e79SGirish Moodalbail 		}
6562ae51e79SGirish Moodalbail 		if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))
6572ae51e79SGirish Moodalbail 			return (DCMD_OK);
6582ae51e79SGirish Moodalbail 		mdb_printf("%?p %-20s %-4d %-4d "
6592ae51e79SGirish Moodalbail 		    "%-6d %-4d %-7d\n",
6600dc2366fSVenugopal Iyer 		    addr, mci.mci_name, mc.mc_ncpus, mc.mc_rx_pollid,
6610dc2366fSVenugopal Iyer 		    mc.mc_rx_workerid, mc.mc_rx_intr_cpu, mc.mc_rx_fanout_cnt);
6622ae51e79SGirish Moodalbail 		break;
6632ae51e79SGirish Moodalbail 
6642ae51e79SGirish Moodalbail 	}
6652ae51e79SGirish Moodalbail 	case MAC_SRS_TXCPU: {
6662ae51e79SGirish Moodalbail 		mac_cpus_t	mc = srs.srs_cpu;
6670dc2366fSVenugopal Iyer 		mac_soft_ring_t *s_ringp, s_ring;
6680dc2366fSVenugopal Iyer 		boolean_t	first = B_TRUE;
6690dc2366fSVenugopal Iyer 		int		i;
6702ae51e79SGirish Moodalbail 
6712ae51e79SGirish Moodalbail 		if (DCMD_HDRSPEC(flags)) {
6720dc2366fSVenugopal Iyer 			mdb_printf("%?s %-12s %?s %8s %8s %8s\n",
6730dc2366fSVenugopal Iyer 			    "", "", "SOFT", "WORKER", "INTR", "RETARGETED");
6740dc2366fSVenugopal Iyer 			mdb_printf("%<u>%?s %-12s %?s %8s %8s %8s%</u>\n",
6750dc2366fSVenugopal Iyer 			    "ADDR", "LINK_NAME", "RING", "CPU", "CPU", "CPU");
6762ae51e79SGirish Moodalbail 		}
6770dc2366fSVenugopal Iyer 		if (!(srs.srs_type & SRST_TX))
6782ae51e79SGirish Moodalbail 			return (DCMD_OK);
6790dc2366fSVenugopal Iyer 
6800dc2366fSVenugopal Iyer 		mdb_printf("%?p %-12s ", addr, mci.mci_name);
6810dc2366fSVenugopal Iyer 
6820dc2366fSVenugopal Iyer 		/*
6830dc2366fSVenugopal Iyer 		 * Case of no soft rings, print the info from
6840dc2366fSVenugopal Iyer 		 * mac_srs_tx_t.
6850dc2366fSVenugopal Iyer 		 */
6860dc2366fSVenugopal Iyer 		if (srs.srs_tx_ring_count == 0) {
6870dc2366fSVenugopal Iyer 			mdb_printf("%?p %8d %8d %8d\n",
6880dc2366fSVenugopal Iyer 			    0, mc.mc_tx_fanout_cpus[0],
6890dc2366fSVenugopal Iyer 			    mc.mc_tx_intr_cpu[0],
6900dc2366fSVenugopal Iyer 			    mc.mc_tx_retargeted_cpu[0]);
6910dc2366fSVenugopal Iyer 			break;
6920dc2366fSVenugopal Iyer 		}
6930dc2366fSVenugopal Iyer 
6940dc2366fSVenugopal Iyer 		for (s_ringp = srs.srs_soft_ring_head, i = 0; s_ringp != NULL;
6950dc2366fSVenugopal Iyer 		    s_ringp = s_ring.s_ring_next, i++) {
6960dc2366fSVenugopal Iyer 			(void) mdb_vread(&s_ring, sizeof (s_ring),
6970dc2366fSVenugopal Iyer 			    (uintptr_t)s_ringp);
6980dc2366fSVenugopal Iyer 			if (first) {
6990dc2366fSVenugopal Iyer 				mdb_printf("%?p %8d %8d %8d\n",
7000dc2366fSVenugopal Iyer 				    s_ringp, mc.mc_tx_fanout_cpus[i],
7010dc2366fSVenugopal Iyer 				    mc.mc_tx_intr_cpu[i],
7020dc2366fSVenugopal Iyer 				    mc.mc_tx_retargeted_cpu[i]);
7030dc2366fSVenugopal Iyer 				first = B_FALSE;
7040dc2366fSVenugopal Iyer 				continue;
7050dc2366fSVenugopal Iyer 			}
7060dc2366fSVenugopal Iyer 			mdb_printf("%?s %-12s %?p %8d %8d %8d\n",
7070dc2366fSVenugopal Iyer 			    "", "", s_ringp, mc.mc_tx_fanout_cpus[i],
7080dc2366fSVenugopal Iyer 			    mc.mc_tx_intr_cpu[i], mc.mc_tx_retargeted_cpu[i]);
7090dc2366fSVenugopal Iyer 		}
7100dc2366fSVenugopal Iyer 		break;
7110dc2366fSVenugopal Iyer 	}
7120dc2366fSVenugopal Iyer 	case MAC_SRS_TXINTR: {
7130dc2366fSVenugopal Iyer 		mac_cpus_t	mc = srs.srs_cpu;
7140dc2366fSVenugopal Iyer 		mac_soft_ring_t *s_ringp, s_ring;
7150dc2366fSVenugopal Iyer 		mac_ring_t	*m_ringp, m_ring;
7160dc2366fSVenugopal Iyer 		boolean_t	first = B_TRUE;
7170dc2366fSVenugopal Iyer 		int		i;
7180dc2366fSVenugopal Iyer 
7190dc2366fSVenugopal Iyer 		if (DCMD_HDRSPEC(flags)) {
7200dc2366fSVenugopal Iyer 			mdb_printf("%?s %-12s %?s %8s %?s %6s %6s\n",
7210dc2366fSVenugopal Iyer 			    "", "", "SOFT", "WORKER", "MAC", "", "INTR");
7220dc2366fSVenugopal Iyer 			mdb_printf("%<u>%?s %-12s %?s %8s %?s %6s %6s%</u>\n",
7230dc2366fSVenugopal Iyer 			    "ADDR", "LINK_NAME", "RING", "CPU", "RING",
7240dc2366fSVenugopal Iyer 			    "SHARED", "CPU");
7250dc2366fSVenugopal Iyer 		}
7260dc2366fSVenugopal Iyer 		if (!(srs.srs_type & SRST_TX))
7270dc2366fSVenugopal Iyer 			return (DCMD_OK);
7280dc2366fSVenugopal Iyer 
7290dc2366fSVenugopal Iyer 		mdb_printf("%?p %-12s ", addr, mci.mci_name);
7300dc2366fSVenugopal Iyer 
7310dc2366fSVenugopal Iyer 		/*
7320dc2366fSVenugopal Iyer 		 * Case of no soft rings, print the info from
7330dc2366fSVenugopal Iyer 		 * mac_srs_tx_t.
7340dc2366fSVenugopal Iyer 		 */
7350dc2366fSVenugopal Iyer 		if (srs.srs_tx_ring_count == 0) {
7360dc2366fSVenugopal Iyer 			m_ringp = srs.srs_tx.st_arg2;
7370dc2366fSVenugopal Iyer 			if (m_ringp != NULL) {
7380dc2366fSVenugopal Iyer 				(void) mdb_vread(&m_ring, sizeof (m_ring),
7390dc2366fSVenugopal Iyer 				    (uintptr_t)m_ringp);
7400dc2366fSVenugopal Iyer 				mdb_printf("%?p %8d %?p %6d %6d\n",
7410dc2366fSVenugopal Iyer 				    0, mc.mc_tx_fanout_cpus[0], m_ringp,
7420dc2366fSVenugopal Iyer 				    m_ring.mr_info.mri_intr.mi_ddi_shared,
7430dc2366fSVenugopal Iyer 				    mc.mc_tx_retargeted_cpu[0]);
7440dc2366fSVenugopal Iyer 			} else {
7450dc2366fSVenugopal Iyer 				mdb_printf("%?p %8d %?p %6d %6d\n",
7460dc2366fSVenugopal Iyer 				    0, mc.mc_tx_fanout_cpus[0], 0,
7470dc2366fSVenugopal Iyer 				    0, mc.mc_tx_retargeted_cpu[0]);
7480dc2366fSVenugopal Iyer 			}
7490dc2366fSVenugopal Iyer 			break;
7500dc2366fSVenugopal Iyer 		}
7510dc2366fSVenugopal Iyer 
7520dc2366fSVenugopal Iyer 		for (s_ringp = srs.srs_soft_ring_head, i = 0; s_ringp != NULL;
7530dc2366fSVenugopal Iyer 		    s_ringp = s_ring.s_ring_next, i++) {
7540dc2366fSVenugopal Iyer 			(void) mdb_vread(&s_ring, sizeof (s_ring),
7550dc2366fSVenugopal Iyer 			    (uintptr_t)s_ringp);
7560dc2366fSVenugopal Iyer 			m_ringp = s_ring.s_ring_tx_arg2;
7570dc2366fSVenugopal Iyer 			(void) mdb_vread(&m_ring, sizeof (m_ring),
7580dc2366fSVenugopal Iyer 			    (uintptr_t)m_ringp);
7590dc2366fSVenugopal Iyer 			if (first) {
7600dc2366fSVenugopal Iyer 				mdb_printf("%?p %8d %?p %6d %6d\n",
7610dc2366fSVenugopal Iyer 				    s_ringp, mc.mc_tx_fanout_cpus[i],
7620dc2366fSVenugopal Iyer 				    m_ringp,
7630dc2366fSVenugopal Iyer 				    m_ring.mr_info.mri_intr.mi_ddi_shared,
7640dc2366fSVenugopal Iyer 				    mc.mc_tx_retargeted_cpu[i]);
7650dc2366fSVenugopal Iyer 				first = B_FALSE;
7660dc2366fSVenugopal Iyer 				continue;
7670dc2366fSVenugopal Iyer 			}
7680dc2366fSVenugopal Iyer 			mdb_printf("%?s %-12s %?p %8d %?p %6d %6d\n",
7690dc2366fSVenugopal Iyer 			    "", "", s_ringp, mc.mc_tx_fanout_cpus[i],
7700dc2366fSVenugopal Iyer 			    m_ringp, m_ring.mr_info.mri_intr.mi_ddi_shared,
7710dc2366fSVenugopal Iyer 			    mc.mc_tx_retargeted_cpu[i]);
7720dc2366fSVenugopal Iyer 		}
7730dc2366fSVenugopal Iyer 		break;
7740dc2366fSVenugopal Iyer 	}
7750dc2366fSVenugopal Iyer 	case MAC_SRS_RXINTR: {
7760dc2366fSVenugopal Iyer 		mac_cpus_t	mc = srs.srs_cpu;
7770dc2366fSVenugopal Iyer 		mac_ring_t	*m_ringp, m_ring;
7780dc2366fSVenugopal Iyer 
7790dc2366fSVenugopal Iyer 		if (DCMD_HDRSPEC(flags)) {
7800dc2366fSVenugopal Iyer 			mdb_printf("%?s %-12s %?s %8s %6s %6s\n",
7810dc2366fSVenugopal Iyer 			    "", "", "MAC", "", "POLL", "INTR");
7820dc2366fSVenugopal Iyer 			mdb_printf("%<u>%?s %-12s %?s %8s %6s %6s%</u>\n",
7830dc2366fSVenugopal Iyer 			    "ADDR", "LINK_NAME", "RING", "SHARED", "CPU",
7840dc2366fSVenugopal Iyer 			    "CPU");
7850dc2366fSVenugopal Iyer 		}
7860dc2366fSVenugopal Iyer 		if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))
7870dc2366fSVenugopal Iyer 			return (DCMD_OK);
7880dc2366fSVenugopal Iyer 
7890dc2366fSVenugopal Iyer 		mdb_printf("%?p %-12s ", addr, mci.mci_name);
7900dc2366fSVenugopal Iyer 
7910dc2366fSVenugopal Iyer 		m_ringp = srs.srs_ring;
7920dc2366fSVenugopal Iyer 		if (m_ringp != NULL) {
7930dc2366fSVenugopal Iyer 			(void) mdb_vread(&m_ring, sizeof (m_ring),
7940dc2366fSVenugopal Iyer 			    (uintptr_t)m_ringp);
7950dc2366fSVenugopal Iyer 			mdb_printf("%?p %8d %6d %6d\n",
7960dc2366fSVenugopal Iyer 			    m_ringp, m_ring.mr_info.mri_intr.mi_ddi_shared,
7970dc2366fSVenugopal Iyer 			    mc.mc_rx_pollid, mc.mc_rx_intr_cpu);
7980dc2366fSVenugopal Iyer 		} else {
7990dc2366fSVenugopal Iyer 			mdb_printf("%?p %8d %6d %6d\n",
8000dc2366fSVenugopal Iyer 			    0, 0, mc.mc_rx_pollid, mc.mc_rx_intr_cpu);
8010dc2366fSVenugopal Iyer 		}
8022ae51e79SGirish Moodalbail 		break;
8032ae51e79SGirish Moodalbail 	}
8042ae51e79SGirish Moodalbail 	case MAC_SRS_RXCPUVERBOSE:
8052ae51e79SGirish Moodalbail 	case MAC_SRS_TXCPUVERBOSE: {
8062ae51e79SGirish Moodalbail 		mac_cpus_t	mc = srs.srs_cpu;
8072ae51e79SGirish Moodalbail 		int		cpu_index = 0, fanout_index = 0, len = 0;
8082ae51e79SGirish Moodalbail 		boolean_t	cpu_done = B_FALSE, fanout_done = B_FALSE;
8092ae51e79SGirish Moodalbail 
8102ae51e79SGirish Moodalbail 		if (DCMD_HDRSPEC(flags)) {
8112ae51e79SGirish Moodalbail 			mdb_printf("%?s %-20s %-20s %-20s\n",
8122ae51e79SGirish Moodalbail 			    "", "", "CPU_COUNT", "FANOUT_CPU_COUNT");
8132ae51e79SGirish Moodalbail 			mdb_printf("%<u>%?s %-20s "
8142ae51e79SGirish Moodalbail 			    "%-20s %-20s%</u>\n",
8152ae51e79SGirish Moodalbail 			    "ADDR", "LINK_NAME",
8162ae51e79SGirish Moodalbail 			    "(CPU_LIST)", "(CPU_LIST)");
8172ae51e79SGirish Moodalbail 		}
8182ae51e79SGirish Moodalbail 		if (((args & MAC_SRS_TX) && !(srs.srs_type & SRST_TX)) ||
8192ae51e79SGirish Moodalbail 		    ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX)))
8202ae51e79SGirish Moodalbail 			return (DCMD_OK);
8212ae51e79SGirish Moodalbail 		mdb_printf("%?p %-20s %-20d %-20d\n", addr, mci.mci_name,
8220dc2366fSVenugopal Iyer 		    mc.mc_ncpus, mc.mc_rx_fanout_cnt);
8230dc2366fSVenugopal Iyer 		if (mc.mc_ncpus == 0 && mc.mc_rx_fanout_cnt == 0)
8242ae51e79SGirish Moodalbail 			break;
8252ae51e79SGirish Moodalbail 		/* print all cpus and cpus for soft rings */
8262ae51e79SGirish Moodalbail 		while (!cpu_done || !fanout_done) {
8272ae51e79SGirish Moodalbail 			boolean_t old_value = cpu_done;
8282ae51e79SGirish Moodalbail 
8292ae51e79SGirish Moodalbail 			if (!cpu_done) {
8302ae51e79SGirish Moodalbail 				mdb_printf("%?s %20s ", "", "");
8312ae51e79SGirish Moodalbail 				cpu_done = mac_srs_print_cpu(&cpu_index,
8322ae51e79SGirish Moodalbail 				    mc.mc_ncpus, mc.mc_cpus, &len);
8332ae51e79SGirish Moodalbail 			}
8342ae51e79SGirish Moodalbail 			if (!fanout_done) {
8352ae51e79SGirish Moodalbail 				if (old_value)
8362ae51e79SGirish Moodalbail 					mdb_printf("%?s %-40s", "", "");
8372ae51e79SGirish Moodalbail 				else
8382ae51e79SGirish Moodalbail 					mdb_printf("%*s", len, "");
8392ae51e79SGirish Moodalbail 				fanout_done = mac_srs_print_cpu(&fanout_index,
8400dc2366fSVenugopal Iyer 				    mc.mc_rx_fanout_cnt,
8410dc2366fSVenugopal Iyer 				    mc.mc_rx_fanout_cpus, NULL);
8422ae51e79SGirish Moodalbail 			}
8432ae51e79SGirish Moodalbail 			mdb_printf("\n");
8442ae51e79SGirish Moodalbail 		}
8452ae51e79SGirish Moodalbail 		break;
8462ae51e79SGirish Moodalbail 	}
8472ae51e79SGirish Moodalbail 	case MAC_SRS_RXSTAT: {
8480dc2366fSVenugopal Iyer 		mac_rx_stats_t *mac_rx_stat = &srs.srs_rx.sr_stat;
8492ae51e79SGirish Moodalbail 
8502ae51e79SGirish Moodalbail 		if (DCMD_HDRSPEC(flags)) {
851fcff38ebSGirish Moodalbail 			mdb_printf("%?s %-16s %8s %8s "
852fcff38ebSGirish Moodalbail 			    "%8s %8s %8s\n",
8532ae51e79SGirish Moodalbail 			    "", "", "INTR", "POLL",
8542ae51e79SGirish Moodalbail 			    "CHAIN", "CHAIN", "CHAIN");
855fcff38ebSGirish Moodalbail 			mdb_printf("%<u>%?s %-16s %8s %8s "
856fcff38ebSGirish Moodalbail 			    "%8s %8s %8s%</u>\n",
8572ae51e79SGirish Moodalbail 			    "ADDR", "LINK_NAME", "COUNT", "COUNT",
8582ae51e79SGirish Moodalbail 			    "<10", "10-50", ">50");
8592ae51e79SGirish Moodalbail 		}
8602ae51e79SGirish Moodalbail 		if (srs.srs_type & SRST_TX)
8612ae51e79SGirish Moodalbail 			return (DCMD_OK);
862fcff38ebSGirish Moodalbail 		mdb_printf("%?p %-16s %8d "
863fcff38ebSGirish Moodalbail 		    "%8d %8d "
864fcff38ebSGirish Moodalbail 		    "%8d %8d\n",
8650dc2366fSVenugopal Iyer 		    addr, mci.mci_name, mac_rx_stat->mrs_intrcnt,
8660dc2366fSVenugopal Iyer 		    mac_rx_stat->mrs_pollcnt, mac_rx_stat->mrs_chaincntundr10,
8670dc2366fSVenugopal Iyer 		    mac_rx_stat->mrs_chaincnt10to50,
8680dc2366fSVenugopal Iyer 		    mac_rx_stat->mrs_chaincntover50);
8692ae51e79SGirish Moodalbail 		break;
8702ae51e79SGirish Moodalbail 	}
8712ae51e79SGirish Moodalbail 	case MAC_SRS_TXSTAT: {
8720dc2366fSVenugopal Iyer 		mac_tx_stats_t *mac_tx_stat = &srs.srs_tx.st_stat;
873fcff38ebSGirish Moodalbail 		mac_soft_ring_t *s_ringp, s_ring;
874fcff38ebSGirish Moodalbail 		boolean_t	first = B_TRUE;
8752ae51e79SGirish Moodalbail 
8762ae51e79SGirish Moodalbail 		if (DCMD_HDRSPEC(flags)) {
877fcff38ebSGirish Moodalbail 			mdb_printf("%?s %-20s %?s %8s %8s %8s\n",
878fcff38ebSGirish Moodalbail 			    "", "", "SOFT", "DROP", "BLOCK", "UNBLOCK");
879fcff38ebSGirish Moodalbail 			mdb_printf("%<u>%?s %-20s %?s %8s %8s %8s%</u>\n",
880fcff38ebSGirish Moodalbail 			    "ADDR", "LINK_NAME", "RING", "COUNT", "COUNT",
881fcff38ebSGirish Moodalbail 			    "COUNT");
882da14cebeSEric Cheng 		}
883da14cebeSEric Cheng 		if (!(srs.srs_type & SRST_TX))
884da14cebeSEric Cheng 			return (DCMD_OK);
885da14cebeSEric Cheng 
886fcff38ebSGirish Moodalbail 		mdb_printf("%?p %-20s ", addr, mci.mci_name);
887fcff38ebSGirish Moodalbail 
888fcff38ebSGirish Moodalbail 		/*
889fcff38ebSGirish Moodalbail 		 * Case of no soft rings, print the info from
890fcff38ebSGirish Moodalbail 		 * mac_srs_tx_t.
891fcff38ebSGirish Moodalbail 		 */
8920dc2366fSVenugopal Iyer 		if (srs.srs_tx_ring_count == 0) {
893fcff38ebSGirish Moodalbail 			mdb_printf("%?p %8d %8d %8d\n",
8940dc2366fSVenugopal Iyer 			    0, mac_tx_stat->mts_sdrops,
8950dc2366fSVenugopal Iyer 			    mac_tx_stat->mts_blockcnt,
8960dc2366fSVenugopal Iyer 			    mac_tx_stat->mts_unblockcnt);
897fcff38ebSGirish Moodalbail 			break;
898fcff38ebSGirish Moodalbail 		}
899fcff38ebSGirish Moodalbail 
900fcff38ebSGirish Moodalbail 		for (s_ringp = srs.srs_soft_ring_head; s_ringp != NULL;
901fcff38ebSGirish Moodalbail 		    s_ringp = s_ring.s_ring_next) {
902fcff38ebSGirish Moodalbail 			(void) mdb_vread(&s_ring, sizeof (s_ring),
903fcff38ebSGirish Moodalbail 			    (uintptr_t)s_ringp);
9040dc2366fSVenugopal Iyer 			mac_tx_stat = &s_ring.s_st_stat;
905fcff38ebSGirish Moodalbail 			if (first) {
906fcff38ebSGirish Moodalbail 				mdb_printf("%?p %8d %8d %8d\n",
9070dc2366fSVenugopal Iyer 				    s_ringp, mac_tx_stat->mts_sdrops,
9080dc2366fSVenugopal Iyer 				    mac_tx_stat->mts_blockcnt,
9090dc2366fSVenugopal Iyer 				    mac_tx_stat->mts_unblockcnt);
910fcff38ebSGirish Moodalbail 				first = B_FALSE;
911fcff38ebSGirish Moodalbail 				continue;
912fcff38ebSGirish Moodalbail 			}
913fcff38ebSGirish Moodalbail 			mdb_printf("%?s %-20s %?p %8d %8d %8d\n",
9140dc2366fSVenugopal Iyer 			    "", "", s_ringp, mac_tx_stat->mts_sdrops,
9150dc2366fSVenugopal Iyer 			    mac_tx_stat->mts_blockcnt,
9160dc2366fSVenugopal Iyer 			    mac_tx_stat->mts_unblockcnt);
917fcff38ebSGirish Moodalbail 		}
918da14cebeSEric Cheng 		break;
919da14cebeSEric Cheng 	}
9202ae51e79SGirish Moodalbail 	case MAC_SRS_NONE: {
921da14cebeSEric Cheng 		if (DCMD_HDRSPEC(flags)) {
9222ae51e79SGirish Moodalbail 			mdb_printf("%<u>%?s %-20s %?s %?s %-3s%</u>\n",
9232ae51e79SGirish Moodalbail 			    "ADDR", "LINK_NAME", "FLENT", "HW RING", "DIR");
924da14cebeSEric Cheng 		}
9252ae51e79SGirish Moodalbail 		mdb_printf("%?p %-20s %?p %?p "
9262ae51e79SGirish Moodalbail 		    "%-3s ",
9272ae51e79SGirish Moodalbail 		    addr, mci.mci_name, srs.srs_flent, srs.srs_ring,
9282ae51e79SGirish Moodalbail 		    (srs.srs_type & SRST_TX ? "TX" : "RX"));
929da14cebeSEric Cheng 		break;
930da14cebeSEric Cheng 	}
9312ae51e79SGirish Moodalbail 	default:
9322ae51e79SGirish Moodalbail 		return (DCMD_USAGE);
933da14cebeSEric Cheng 	}
934da14cebeSEric Cheng 	return (DCMD_OK);
935da14cebeSEric Cheng }
936da14cebeSEric Cheng 
937da14cebeSEric Cheng static int
mac_srs_walk_init(mdb_walk_state_t * wsp)938da14cebeSEric Cheng mac_srs_walk_init(mdb_walk_state_t *wsp)
939da14cebeSEric Cheng {
940da14cebeSEric Cheng 	if (mdb_layered_walk(LAYERED_WALKER_FOR_SRS, wsp) == -1) {
941da14cebeSEric Cheng 		mdb_warn("failed to walk 'mac_srs'");
942da14cebeSEric Cheng 		return (WALK_ERR);
943da14cebeSEric Cheng 	}
944da14cebeSEric Cheng 	return (WALK_NEXT);
945da14cebeSEric Cheng }
946da14cebeSEric Cheng 
947da14cebeSEric Cheng static char *
mac_ring_state2str(mac_ring_state_t state)948da14cebeSEric Cheng mac_ring_state2str(mac_ring_state_t state)
949da14cebeSEric Cheng {
950da14cebeSEric Cheng 	switch (state) {
951da14cebeSEric Cheng 	case MR_FREE:
952da14cebeSEric Cheng 		return ("free");
953da14cebeSEric Cheng 	case MR_NEWLY_ADDED:
954da14cebeSEric Cheng 		return ("new");
955da14cebeSEric Cheng 	case MR_INUSE:
956da14cebeSEric Cheng 		return ("inuse");
957da14cebeSEric Cheng 	}
958da14cebeSEric Cheng 	return ("--");
959da14cebeSEric Cheng }
960da14cebeSEric Cheng 
961da14cebeSEric Cheng static char *
mac_ring_classify2str(mac_classify_type_t classify)962da14cebeSEric Cheng mac_ring_classify2str(mac_classify_type_t classify)
963da14cebeSEric Cheng {
964da14cebeSEric Cheng 	switch (classify) {
965da14cebeSEric Cheng 	case MAC_NO_CLASSIFIER:
966da14cebeSEric Cheng 		return ("no");
967da14cebeSEric Cheng 	case MAC_SW_CLASSIFIER:
968da14cebeSEric Cheng 		return ("sw");
969da14cebeSEric Cheng 	case MAC_HW_CLASSIFIER:
970da14cebeSEric Cheng 		return ("hw");
971*45948e49SRyan Zezeski 	case MAC_PASSTHRU_CLASSIFIER:
972*45948e49SRyan Zezeski 		return ("pass");
973da14cebeSEric Cheng 	}
974da14cebeSEric Cheng 	return ("--");
975da14cebeSEric Cheng }
976da14cebeSEric Cheng 
977da14cebeSEric Cheng static int
mac_ring_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)978da14cebeSEric Cheng mac_ring_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
979da14cebeSEric Cheng {
980da14cebeSEric Cheng 	mac_ring_t		ring;
981da14cebeSEric Cheng 	mac_group_t		group;
982da14cebeSEric Cheng 	flow_entry_t		flent;
983da14cebeSEric Cheng 	mac_soft_ring_set_t	srs;
984da14cebeSEric Cheng 
985da14cebeSEric Cheng 	if (!(flags & DCMD_ADDRSPEC)) {
986da14cebeSEric Cheng 		if (mdb_walk_dcmd("mac_ring", "mac_ring", argc, argv) == -1) {
987da14cebeSEric Cheng 			mdb_warn("failed to walk 'mac_ring'");
988da14cebeSEric Cheng 			return (DCMD_ERR);
989da14cebeSEric Cheng 		}
990da14cebeSEric Cheng 		return (DCMD_OK);
991da14cebeSEric Cheng 	}
992da14cebeSEric Cheng 	if (mdb_vread(&ring, sizeof (ring), addr) == -1) {
993da14cebeSEric Cheng 		mdb_warn("failed to read struct mac_ring_s at %p", addr);
994da14cebeSEric Cheng 		return (DCMD_ERR);
995da14cebeSEric Cheng 	}
996da14cebeSEric Cheng 	bzero(&flent, sizeof (flent));
997da14cebeSEric Cheng 	if (mdb_vread(&srs, sizeof (srs), (uintptr_t)ring.mr_srs) != -1) {
998da14cebeSEric Cheng 		(void) mdb_vread(&flent, sizeof (flent),
999da14cebeSEric Cheng 		    (uintptr_t)srs.srs_flent);
1000da14cebeSEric Cheng 	}
1001da14cebeSEric Cheng 	(void) mdb_vread(&group, sizeof (group), (uintptr_t)ring.mr_gh);
1002da14cebeSEric Cheng 	if (DCMD_HDRSPEC(flags)) {
1003da14cebeSEric Cheng 		mdb_printf("%<u>%?s %4s %5s %4s %?s "
1004da14cebeSEric Cheng 		    "%5s %?s %?s %s %</u>\n",
1005da14cebeSEric Cheng 		    "ADDR", "TYPE", "STATE", "FLAG", "GROUP",
1006da14cebeSEric Cheng 		    "CLASS", "MIP", "SRS", "FLOW NAME");
1007da14cebeSEric Cheng 	}
1008da14cebeSEric Cheng 	mdb_printf("%?p %-4s "
1009da14cebeSEric Cheng 	    "%5s %04x "
1010da14cebeSEric Cheng 	    "%?p %-5s "
1011da14cebeSEric Cheng 	    "%?p %?p %s\n",
1012da14cebeSEric Cheng 	    addr, ((ring.mr_type == 1)? "RX" : "TX"),
1013da14cebeSEric Cheng 	    mac_ring_state2str(ring.mr_state), ring.mr_flag,
1014da14cebeSEric Cheng 	    ring.mr_gh, mac_ring_classify2str(ring.mr_classify_type),
1015da14cebeSEric Cheng 	    group.mrg_mh, ring.mr_srs, flent.fe_flow_name);
1016da14cebeSEric Cheng 	return (DCMD_OK);
1017da14cebeSEric Cheng }
1018da14cebeSEric Cheng 
1019da14cebeSEric Cheng static int
mac_ring_walk_init(mdb_walk_state_t * wsp)1020da14cebeSEric Cheng mac_ring_walk_init(mdb_walk_state_t *wsp)
1021da14cebeSEric Cheng {
1022da14cebeSEric Cheng 	if (mdb_layered_walk(LAYERED_WALKER_FOR_RING, wsp) == -1) {
1023da14cebeSEric Cheng 		mdb_warn("failed to walk `mac_ring`");
1024da14cebeSEric Cheng 		return (WALK_ERR);
1025da14cebeSEric Cheng 	}
1026da14cebeSEric Cheng 	return (WALK_NEXT);
1027da14cebeSEric Cheng }
1028da14cebeSEric Cheng 
1029da14cebeSEric Cheng static void
mac_ring_help(void)1030da14cebeSEric Cheng mac_ring_help(void)
1031da14cebeSEric Cheng {
1032da14cebeSEric Cheng 	mdb_printf("If an address is specified, then mac_ring_t "
1033da14cebeSEric Cheng 	    "structure at that address is printed. Otherwise all the "
1034da14cebeSEric Cheng 	    "hardware rings in the system are printed.\n");
1035da14cebeSEric Cheng }
1036da14cebeSEric Cheng 
1037d47ced1fSRobert Mustacchi /*
1038d47ced1fSRobert Mustacchi  * To walk groups we have to have our own somewhat-complicated state machine. We
1039d47ced1fSRobert Mustacchi  * basically start by walking the mac_impl_t walker as all groups are stored off
1040d47ced1fSRobert Mustacchi  * of the various mac_impl_t in the system. The tx and rx rings are kept
1041d47ced1fSRobert Mustacchi  * separately. So we'll need to walk through all the rx rings and then all of
1042d47ced1fSRobert Mustacchi  * the tx rings.
1043d47ced1fSRobert Mustacchi  */
1044d47ced1fSRobert Mustacchi static int
mac_group_walk_init(mdb_walk_state_t * wsp)1045d47ced1fSRobert Mustacchi mac_group_walk_init(mdb_walk_state_t *wsp)
1046d47ced1fSRobert Mustacchi {
1047d47ced1fSRobert Mustacchi 	int ret;
1048d47ced1fSRobert Mustacchi 
1049892ad162SToomas Soome 	if (wsp->walk_addr != 0) {
1050d47ced1fSRobert Mustacchi 		mdb_warn("non-global walks are not supported\n");
1051d47ced1fSRobert Mustacchi 		return (WALK_ERR);
1052d47ced1fSRobert Mustacchi 	}
1053d47ced1fSRobert Mustacchi 
1054d47ced1fSRobert Mustacchi 	if ((ret = mdb_layered_walk(LAYERED_WALKER_FOR_GROUP, wsp)) == -1) {
1055d47ced1fSRobert Mustacchi 		mdb_warn("couldn't walk '%s'", LAYERED_WALKER_FOR_GROUP);
1056d47ced1fSRobert Mustacchi 		return (ret);
1057d47ced1fSRobert Mustacchi 	}
1058d47ced1fSRobert Mustacchi 
1059d47ced1fSRobert Mustacchi 	return (WALK_NEXT);
1060d47ced1fSRobert Mustacchi }
1061d47ced1fSRobert Mustacchi 
1062d47ced1fSRobert Mustacchi static int
mac_group_walk_step(mdb_walk_state_t * wsp)1063d47ced1fSRobert Mustacchi mac_group_walk_step(mdb_walk_state_t *wsp)
1064d47ced1fSRobert Mustacchi {
1065d47ced1fSRobert Mustacchi 	int ret;
1066d47ced1fSRobert Mustacchi 	mac_impl_t mi;
1067d47ced1fSRobert Mustacchi 	mac_group_t mg;
1068d47ced1fSRobert Mustacchi 	uintptr_t mgp;
1069d47ced1fSRobert Mustacchi 
1070d47ced1fSRobert Mustacchi 	/*
1071d47ced1fSRobert Mustacchi 	 * Nothing to do if we can't find the layer above us. But the kmem
1072d47ced1fSRobert Mustacchi 	 * walkers are a bit unsporting, they don't actually read in the data
1073d47ced1fSRobert Mustacchi 	 * for us.
1074d47ced1fSRobert Mustacchi 	 */
1075892ad162SToomas Soome 	if (wsp->walk_addr == 0)
1076d47ced1fSRobert Mustacchi 		return (WALK_DONE);
1077d47ced1fSRobert Mustacchi 
1078d47ced1fSRobert Mustacchi 	if (mdb_vread(&mi, sizeof (mac_impl_t), wsp->walk_addr) == -1) {
1079d47ced1fSRobert Mustacchi 		mdb_warn("failed to read mac_impl_t at %p", wsp->walk_addr);
1080d47ced1fSRobert Mustacchi 		return (DCMD_ERR);
1081d47ced1fSRobert Mustacchi 	}
1082d47ced1fSRobert Mustacchi 
1083d47ced1fSRobert Mustacchi 	/*
1084d47ced1fSRobert Mustacchi 	 * First go for rx groups, then tx groups.
1085d47ced1fSRobert Mustacchi 	 */
1086d47ced1fSRobert Mustacchi 	mgp = (uintptr_t)mi.mi_rx_groups;
1087892ad162SToomas Soome 	while (mgp != 0) {
1088d47ced1fSRobert Mustacchi 		if (mdb_vread(&mg, sizeof (mac_group_t), mgp) == -1) {
1089d47ced1fSRobert Mustacchi 			mdb_warn("failed to read mac_group_t at %p", mgp);
1090d47ced1fSRobert Mustacchi 			return (WALK_ERR);
1091d47ced1fSRobert Mustacchi 		}
1092d47ced1fSRobert Mustacchi 
1093d47ced1fSRobert Mustacchi 		ret = wsp->walk_callback(mgp, &mg, wsp->walk_cbdata);
1094d47ced1fSRobert Mustacchi 		if (ret != WALK_NEXT)
1095d47ced1fSRobert Mustacchi 			return (ret);
1096d47ced1fSRobert Mustacchi 		mgp = (uintptr_t)mg.mrg_next;
1097d47ced1fSRobert Mustacchi 	}
1098d47ced1fSRobert Mustacchi 
1099d47ced1fSRobert Mustacchi 	mgp = (uintptr_t)mi.mi_tx_groups;
1100892ad162SToomas Soome 	while (mgp != 0) {
1101d47ced1fSRobert Mustacchi 		if (mdb_vread(&mg, sizeof (mac_group_t), mgp) == -1) {
1102d47ced1fSRobert Mustacchi 			mdb_warn("failed to read mac_group_t at %p", mgp);
1103d47ced1fSRobert Mustacchi 			return (WALK_ERR);
1104d47ced1fSRobert Mustacchi 		}
1105d47ced1fSRobert Mustacchi 
1106d47ced1fSRobert Mustacchi 		ret = wsp->walk_callback(mgp, &mg, wsp->walk_cbdata);
1107d47ced1fSRobert Mustacchi 		if (ret != WALK_NEXT)
1108d47ced1fSRobert Mustacchi 			return (ret);
1109d47ced1fSRobert Mustacchi 		mgp = (uintptr_t)mg.mrg_next;
1110d47ced1fSRobert Mustacchi 	}
1111d47ced1fSRobert Mustacchi 
1112d47ced1fSRobert Mustacchi 	return (WALK_NEXT);
1113d47ced1fSRobert Mustacchi }
1114d47ced1fSRobert Mustacchi 
1115d47ced1fSRobert Mustacchi static int
mac_group_count_clients(mac_group_t * mgp)1116d47ced1fSRobert Mustacchi mac_group_count_clients(mac_group_t *mgp)
1117d47ced1fSRobert Mustacchi {
1118d47ced1fSRobert Mustacchi 	int clients = 0;
1119d47ced1fSRobert Mustacchi 	uintptr_t mcp = (uintptr_t)mgp->mrg_clients;
1120d47ced1fSRobert Mustacchi 
1121892ad162SToomas Soome 	while (mcp != 0) {
1122d47ced1fSRobert Mustacchi 		mac_grp_client_t c;
1123d47ced1fSRobert Mustacchi 
1124d47ced1fSRobert Mustacchi 		if (mdb_vread(&c, sizeof (c), mcp) == -1) {
1125d47ced1fSRobert Mustacchi 			mdb_warn("failed to read mac_grp_client_t at %p", mcp);
1126d47ced1fSRobert Mustacchi 			return (-1);
1127d47ced1fSRobert Mustacchi 		}
1128d47ced1fSRobert Mustacchi 		clients++;
1129d47ced1fSRobert Mustacchi 		mcp = (uintptr_t)c.mgc_next;
1130d47ced1fSRobert Mustacchi 	}
1131d47ced1fSRobert Mustacchi 
1132d47ced1fSRobert Mustacchi 	return (clients);
1133d47ced1fSRobert Mustacchi }
1134d47ced1fSRobert Mustacchi 
1135d47ced1fSRobert Mustacchi static const char *
mac_group_type(mac_group_t * mgp)1136d47ced1fSRobert Mustacchi mac_group_type(mac_group_t *mgp)
1137d47ced1fSRobert Mustacchi {
1138d47ced1fSRobert Mustacchi 	const char *ret;
1139d47ced1fSRobert Mustacchi 
1140d47ced1fSRobert Mustacchi 	switch (mgp->mrg_type) {
1141d47ced1fSRobert Mustacchi 	case MAC_RING_TYPE_RX:
1142d47ced1fSRobert Mustacchi 		ret = "RECEIVE";
1143d47ced1fSRobert Mustacchi 		break;
1144d47ced1fSRobert Mustacchi 	case MAC_RING_TYPE_TX:
1145d47ced1fSRobert Mustacchi 		ret = "TRANSMIT";
1146d47ced1fSRobert Mustacchi 		break;
1147d47ced1fSRobert Mustacchi 	default:
1148d47ced1fSRobert Mustacchi 		ret = "UNKNOWN";
1149d47ced1fSRobert Mustacchi 		break;
1150d47ced1fSRobert Mustacchi 	}
1151d47ced1fSRobert Mustacchi 
1152d47ced1fSRobert Mustacchi 	return (ret);
1153d47ced1fSRobert Mustacchi }
1154d47ced1fSRobert Mustacchi 
1155d47ced1fSRobert Mustacchi static const char *
mac_group_state(mac_group_t * mgp)1156d47ced1fSRobert Mustacchi mac_group_state(mac_group_t *mgp)
1157d47ced1fSRobert Mustacchi {
1158d47ced1fSRobert Mustacchi 	const char *ret;
1159d47ced1fSRobert Mustacchi 
1160d47ced1fSRobert Mustacchi 	switch (mgp->mrg_state) {
1161d47ced1fSRobert Mustacchi 	case MAC_GROUP_STATE_UNINIT:
1162d47ced1fSRobert Mustacchi 		ret = "UNINT";
1163d47ced1fSRobert Mustacchi 		break;
1164d47ced1fSRobert Mustacchi 	case MAC_GROUP_STATE_REGISTERED:
1165d47ced1fSRobert Mustacchi 		ret = "REGISTERED";
1166d47ced1fSRobert Mustacchi 		break;
1167d47ced1fSRobert Mustacchi 	case MAC_GROUP_STATE_RESERVED:
1168d47ced1fSRobert Mustacchi 		ret = "RESERVED";
1169d47ced1fSRobert Mustacchi 		break;
1170d47ced1fSRobert Mustacchi 	case MAC_GROUP_STATE_SHARED:
1171d47ced1fSRobert Mustacchi 		ret = "SHARED";
1172d47ced1fSRobert Mustacchi 		break;
1173d47ced1fSRobert Mustacchi 	default:
1174d47ced1fSRobert Mustacchi 		ret = "UNKNOWN";
1175d47ced1fSRobert Mustacchi 		break;
1176d47ced1fSRobert Mustacchi 	}
1177d47ced1fSRobert Mustacchi 
1178d47ced1fSRobert Mustacchi 	return (ret);
1179d47ced1fSRobert Mustacchi }
1180d47ced1fSRobert Mustacchi 
1181d47ced1fSRobert Mustacchi static int
mac_group_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1182d47ced1fSRobert Mustacchi mac_group_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1183d47ced1fSRobert Mustacchi {
1184d47ced1fSRobert Mustacchi 	uint_t		args = MAC_SRS_NONE;
1185d47ced1fSRobert Mustacchi 	mac_group_t	mg;
1186d47ced1fSRobert Mustacchi 	int		clients;
1187d47ced1fSRobert Mustacchi 
1188d47ced1fSRobert Mustacchi 	if (!(flags & DCMD_ADDRSPEC)) {
1189d47ced1fSRobert Mustacchi 		if (mdb_walk_dcmd("mac_group", "mac_group", argc, argv) == -1) {
1190d47ced1fSRobert Mustacchi 			mdb_warn("failed to walk 'mac_group'");
1191d47ced1fSRobert Mustacchi 			return (DCMD_ERR);
1192d47ced1fSRobert Mustacchi 		}
1193d47ced1fSRobert Mustacchi 
1194d47ced1fSRobert Mustacchi 		return (DCMD_OK);
1195d47ced1fSRobert Mustacchi 	}
1196d47ced1fSRobert Mustacchi 
1197d47ced1fSRobert Mustacchi 	if (mdb_getopts(argc, argv,
1198d47ced1fSRobert Mustacchi 	    'r', MDB_OPT_SETBITS, MAC_GROUP_RX, &args,
1199d47ced1fSRobert Mustacchi 	    't', MDB_OPT_SETBITS, MAC_GROUP_TX, &args,
1200d47ced1fSRobert Mustacchi 	    'u', MDB_OPT_SETBITS, MAC_GROUP_UNINIT, &args,
1201d47ced1fSRobert Mustacchi 	    NULL) != argc)
1202d47ced1fSRobert Mustacchi 		return (DCMD_USAGE);
1203d47ced1fSRobert Mustacchi 
1204d47ced1fSRobert Mustacchi 	if (mdb_vread(&mg, sizeof (mac_group_t), addr) == -1) {
1205d47ced1fSRobert Mustacchi 		mdb_warn("failed to read mac_group_t at %p", addr);
1206d47ced1fSRobert Mustacchi 		return (DCMD_ERR);
1207d47ced1fSRobert Mustacchi 	}
1208d47ced1fSRobert Mustacchi 
1209d47ced1fSRobert Mustacchi 	if (DCMD_HDRSPEC(flags) && !(flags & DCMD_PIPE_OUT)) {
1210d47ced1fSRobert Mustacchi 		mdb_printf("%<u>%-?s %-8s %-10s %6s %8s %-?s%</u>\n",
1211d47ced1fSRobert Mustacchi 		    "ADDR", "TYPE", "STATE", "NRINGS", "NCLIENTS", "RINGS");
1212d47ced1fSRobert Mustacchi 	}
1213d47ced1fSRobert Mustacchi 
1214d47ced1fSRobert Mustacchi 	if ((args & MAC_GROUP_RX) != 0 && mg.mrg_type != MAC_RING_TYPE_RX)
1215d47ced1fSRobert Mustacchi 		return (DCMD_OK);
1216d47ced1fSRobert Mustacchi 	if ((args & MAC_GROUP_TX) != 0 && mg.mrg_type != MAC_RING_TYPE_TX)
1217d47ced1fSRobert Mustacchi 		return (DCMD_OK);
1218d47ced1fSRobert Mustacchi 
1219d47ced1fSRobert Mustacchi 	/*
1220d47ced1fSRobert Mustacchi 	 * By default, don't show uninitialized groups. They're not very
1221d47ced1fSRobert Mustacchi 	 * interesting. They have no rings and no clients.
1222d47ced1fSRobert Mustacchi 	 */
1223d47ced1fSRobert Mustacchi 	if (mg.mrg_state == MAC_GROUP_STATE_UNINIT &&
1224d47ced1fSRobert Mustacchi 	    (args & MAC_GROUP_UNINIT) == 0)
1225d47ced1fSRobert Mustacchi 		return (DCMD_OK);
1226d47ced1fSRobert Mustacchi 
1227d47ced1fSRobert Mustacchi 	if (flags & DCMD_PIPE_OUT) {
1228d47ced1fSRobert Mustacchi 		mdb_printf("%lr\n", addr);
1229d47ced1fSRobert Mustacchi 		return (DCMD_OK);
1230d47ced1fSRobert Mustacchi 	}
1231d47ced1fSRobert Mustacchi 
1232d47ced1fSRobert Mustacchi 	clients = mac_group_count_clients(&mg);
1233d47ced1fSRobert Mustacchi 	mdb_printf("%?p %-8s %-10s %6d %8d %?p\n", addr, mac_group_type(&mg),
1234d47ced1fSRobert Mustacchi 	    mac_group_state(&mg), mg.mrg_cur_count, clients, mg.mrg_rings);
1235d47ced1fSRobert Mustacchi 
1236d47ced1fSRobert Mustacchi 	return (DCMD_OK);
1237d47ced1fSRobert Mustacchi }
1238d47ced1fSRobert Mustacchi 
1239da14cebeSEric Cheng /* Supported dee-commands */
1240da14cebeSEric Cheng static const mdb_dcmd_t dcmds[] = {
1241da14cebeSEric Cheng 	{"mac_flow", "?[-u] [-aprtsm]", "display Flow Entry structures",
1242da14cebeSEric Cheng 	    mac_flow_dcmd, mac_flow_help},
1243d47ced1fSRobert Mustacchi 	{"mac_group", "?[-rtu]", "display MAC Ring Groups", mac_group_dcmd,
1244d47ced1fSRobert Mustacchi 	    NULL },
12450dc2366fSVenugopal Iyer 	{"mac_srs", "?[ -r[i|s|c[v]] | -t[i|s|c[v]] ]",
12460dc2366fSVenugopal Iyer 	    "display MAC Soft Ring Set" " structures", mac_srs_dcmd,
12470dc2366fSVenugopal Iyer 	    mac_srs_help},
1248da14cebeSEric Cheng 	{"mac_ring", "?", "display MAC ring (hardware) structures",
1249da14cebeSEric Cheng 	    mac_ring_dcmd, mac_ring_help},
1250da14cebeSEric Cheng 	{ NULL }
1251da14cebeSEric Cheng };
1252da14cebeSEric Cheng 
1253da14cebeSEric Cheng /* Supported walkers */
1254da14cebeSEric Cheng static const mdb_walker_t walkers[] = {
1255da14cebeSEric Cheng 	{"mac_flow", "walk list of flow entry structures", mac_flow_walk_init,
1256da14cebeSEric Cheng 	    mac_common_walk_step, NULL, NULL},
1257d47ced1fSRobert Mustacchi 	{"mac_group", "walk list of ring group structures", mac_group_walk_init,
1258d47ced1fSRobert Mustacchi 	    mac_group_walk_step, NULL, NULL},
1259da14cebeSEric Cheng 	{"mac_srs", "walk list of mac soft ring set structures",
1260da14cebeSEric Cheng 	    mac_srs_walk_init, mac_common_walk_step, NULL, NULL},
1261da14cebeSEric Cheng 	{"mac_ring", "walk list of mac ring structures", mac_ring_walk_init,
1262da14cebeSEric Cheng 	    mac_common_walk_step, NULL, NULL},
1263da14cebeSEric Cheng 	{ NULL }
1264da14cebeSEric Cheng };
1265da14cebeSEric Cheng 
1266da14cebeSEric Cheng static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
1267da14cebeSEric Cheng 
1268da14cebeSEric Cheng const mdb_modinfo_t *
_mdb_init(void)1269da14cebeSEric Cheng _mdb_init(void)
1270da14cebeSEric Cheng {
1271da14cebeSEric Cheng 	return (&modinfo);
1272da14cebeSEric Cheng }
1273