1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * MAC Services Module
28 */
29
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32 #include <sys/stream.h>
33 #include <sys/kstat.h>
34 #include <sys/mac.h>
35 #include <sys/mac_impl.h>
36 #include <sys/mac_client_impl.h>
37 #include <sys/mac_stat.h>
38 #include <sys/mac_soft_ring.h>
39 #include <sys/vlan.h>
40
41 #define MAC_KSTAT_NAME "mac"
42 #define MAC_KSTAT_CLASS "net"
43
44 enum mac_stat {
45 MAC_STAT_LCL,
46 MAC_STAT_LCLBYTES,
47 MAC_STAT_INTRS,
48 MAC_STAT_INTRBYTES,
49 MAC_STAT_POLLS,
50 MAC_STAT_POLLBYTES,
51 MAC_STAT_RXSDROPS,
52 MAC_STAT_CHU10,
53 MAC_STAT_CH10T50,
54 MAC_STAT_CHO50,
55 MAC_STAT_BLOCK,
56 MAC_STAT_UNBLOCK,
57 MAC_STAT_TXSDROPS,
58 MAC_STAT_TX_ERRORS,
59 MAC_STAT_MACSPOOFED,
60 MAC_STAT_IPSPOOFED,
61 MAC_STAT_DHCPSPOOFED,
62 MAC_STAT_RESTRICTED,
63 MAC_STAT_DHCPDROPPED,
64 MAC_STAT_MULTIRCVBYTES,
65 MAC_STAT_BRDCSTRCVBYTES,
66 MAC_STAT_MULTIXMTBYTES,
67 MAC_STAT_BRDCSTXMTBYTES
68 };
69
70 static mac_stat_info_t i_mac_si[] = {
71 { MAC_STAT_IFSPEED, "ifspeed", KSTAT_DATA_UINT64, 0 },
72 { MAC_STAT_MULTIRCV, "multircv", KSTAT_DATA_UINT32, 0 },
73 { MAC_STAT_BRDCSTRCV, "brdcstrcv", KSTAT_DATA_UINT32, 0 },
74 { MAC_STAT_MULTIXMT, "multixmt", KSTAT_DATA_UINT32, 0 },
75 { MAC_STAT_BRDCSTXMT, "brdcstxmt", KSTAT_DATA_UINT32, 0 },
76 { MAC_STAT_NORCVBUF, "norcvbuf", KSTAT_DATA_UINT32, 0 },
77 { MAC_STAT_IERRORS, "ierrors", KSTAT_DATA_UINT32, 0 },
78 { MAC_STAT_UNKNOWNS, "unknowns", KSTAT_DATA_UINT32, 0 },
79 { MAC_STAT_NOXMTBUF, "noxmtbuf", KSTAT_DATA_UINT32, 0 },
80 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT32, 0 },
81 { MAC_STAT_COLLISIONS, "collisions", KSTAT_DATA_UINT32, 0 },
82 { MAC_STAT_UNDERFLOWS, "uflo", KSTAT_DATA_UINT32, 0 },
83 { MAC_STAT_OVERFLOWS, "oflo", KSTAT_DATA_UINT32, 0 },
84 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT32, 0 },
85 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT32, 0 },
86 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT32, 0 },
87 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT32, 0 },
88 { MAC_STAT_RBYTES, "rbytes64", KSTAT_DATA_UINT64, 0 },
89 { MAC_STAT_IPACKETS, "ipackets64", KSTAT_DATA_UINT64, 0 },
90 { MAC_STAT_OBYTES, "obytes64", KSTAT_DATA_UINT64, 0 },
91 { MAC_STAT_OPACKETS, "opackets64", KSTAT_DATA_UINT64, 0 }
92 };
93 #define MAC_NKSTAT \
94 (sizeof (i_mac_si) / sizeof (mac_stat_info_t))
95
96 static mac_stat_info_t i_mac_mod_si[] = {
97 { MAC_STAT_LINK_STATE, "link_state", KSTAT_DATA_UINT32,
98 (uint64_t)LINK_STATE_UNKNOWN },
99 { MAC_STAT_LINK_UP, "link_up", KSTAT_DATA_UINT32, 0 },
100 { MAC_STAT_PROMISC, "promisc", KSTAT_DATA_UINT32, 0 }
101 };
102 #define MAC_MOD_NKSTAT \
103 (sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t))
104
105 #define MAC_MOD_KSTAT_OFFSET 0
106 #define MAC_KSTAT_OFFSET MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT
107 #define MAC_TYPE_KSTAT_OFFSET MAC_KSTAT_OFFSET + MAC_NKSTAT
108
109 /*
110 * Definitions for per rx ring statistics
111 */
112 static mac_stat_info_t i_mac_rx_ring_si[] = {
113 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT64, 0},
114 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT64, 0},
115 { MAC_STAT_HDROPS, "hdrops", KSTAT_DATA_UINT64, 0}
116 };
117 #define MAC_RX_RING_NKSTAT \
118 (sizeof (i_mac_rx_ring_si) / sizeof (mac_stat_info_t))
119
120 /*
121 * Definitions for per tx ring statistics
122 */
123 static mac_stat_info_t i_mac_tx_ring_si[] = {
124 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT64, 0},
125 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT64, 0}
126 };
127 #define MAC_TX_RING_NKSTAT \
128 (sizeof (i_mac_tx_ring_si) / sizeof (mac_stat_info_t))
129
130
131 /*
132 * Definitions for per software lane tx statistics
133 */
134 static mac_stat_info_t i_mac_tx_swlane_si[] = {
135 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT64, 0},
136 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT64, 0},
137 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT64, 0},
138 { MAC_STAT_BLOCK, "blockcnt", KSTAT_DATA_UINT64, 0},
139 { MAC_STAT_UNBLOCK, "unblockcnt", KSTAT_DATA_UINT64, 0},
140 { MAC_STAT_TXSDROPS, "txsdrops", KSTAT_DATA_UINT64, 0}
141 };
142 #define MAC_TX_SWLANE_NKSTAT \
143 (sizeof (i_mac_tx_swlane_si) / sizeof (mac_stat_info_t))
144
145 /*
146 * Definitions for per software lane rx statistics
147 */
148 static mac_stat_info_t i_mac_rx_swlane_si[] = {
149 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT64, 0},
150 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT64, 0},
151 { MAC_STAT_LCL, "local", KSTAT_DATA_UINT64, 0},
152 { MAC_STAT_LCLBYTES, "localbytes", KSTAT_DATA_UINT64, 0},
153 { MAC_STAT_INTRS, "intrs", KSTAT_DATA_UINT64, 0},
154 { MAC_STAT_INTRBYTES, "intrbytes", KSTAT_DATA_UINT64, 0},
155 { MAC_STAT_RXSDROPS, "rxsdrops", KSTAT_DATA_UINT64, 0}
156 };
157 #define MAC_RX_SWLANE_NKSTAT \
158 (sizeof (i_mac_rx_swlane_si) / sizeof (mac_stat_info_t))
159
160 /*
161 * Definitions for per hardware lane rx statistics
162 */
163 static mac_stat_info_t i_mac_rx_hwlane_si[] = {
164 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT64, 0},
165 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT64, 0},
166 { MAC_STAT_INTRS, "intrs", KSTAT_DATA_UINT64, 0},
167 { MAC_STAT_INTRBYTES, "intrbytes", KSTAT_DATA_UINT64, 0},
168 { MAC_STAT_POLLS, "polls", KSTAT_DATA_UINT64, 0},
169 { MAC_STAT_POLLBYTES, "pollbytes", KSTAT_DATA_UINT64, 0},
170 { MAC_STAT_RXSDROPS, "rxsdrops", KSTAT_DATA_UINT64, 0},
171 { MAC_STAT_CHU10, "chainunder10", KSTAT_DATA_UINT64, 0},
172 { MAC_STAT_CH10T50, "chain10to50", KSTAT_DATA_UINT64, 0},
173 { MAC_STAT_CHO50, "chainover50", KSTAT_DATA_UINT64, 0}
174 };
175 #define MAC_RX_HWLANE_NKSTAT \
176 (sizeof (i_mac_rx_hwlane_si) / sizeof (mac_stat_info_t))
177
178 /*
179 * Definitions for misc statistics
180 */
181 static mac_stat_info_t i_mac_misc_si[] = {
182 { MAC_STAT_MULTIRCV, "multircv", KSTAT_DATA_UINT64, 0},
183 { MAC_STAT_BRDCSTRCV, "brdcstrcv", KSTAT_DATA_UINT64, 0},
184 { MAC_STAT_MULTIXMT, "multixmt", KSTAT_DATA_UINT64, 0},
185 { MAC_STAT_BRDCSTXMT, "brdcstxmt", KSTAT_DATA_UINT64, 0},
186 { MAC_STAT_MULTIRCVBYTES, "multircvbytes", KSTAT_DATA_UINT64, 0},
187 { MAC_STAT_BRDCSTRCVBYTES, "brdcstrcvbytes", KSTAT_DATA_UINT64, 0},
188 { MAC_STAT_MULTIXMTBYTES, "multixmtbytes", KSTAT_DATA_UINT64, 0},
189 { MAC_STAT_BRDCSTXMTBYTES, "brdcstxmtbytes", KSTAT_DATA_UINT64, 0},
190 { MAC_STAT_TX_ERRORS, "txerrors", KSTAT_DATA_UINT64, 0},
191 { MAC_STAT_MACSPOOFED, "macspoofed", KSTAT_DATA_UINT64, 0},
192 { MAC_STAT_IPSPOOFED, "ipspoofed", KSTAT_DATA_UINT64, 0},
193 { MAC_STAT_DHCPSPOOFED, "dhcpspoofed", KSTAT_DATA_UINT64, 0},
194 { MAC_STAT_RESTRICTED, "restricted", KSTAT_DATA_UINT64, 0},
195 { MAC_STAT_DHCPDROPPED, "dhcpdropped", KSTAT_DATA_UINT64, 0},
196 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT64, 0},
197 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT64, 0},
198 { MAC_STAT_LCL, "local", KSTAT_DATA_UINT64, 0},
199 { MAC_STAT_LCLBYTES, "localbytes", KSTAT_DATA_UINT64, 0},
200 { MAC_STAT_INTRS, "intrs", KSTAT_DATA_UINT64, 0},
201 { MAC_STAT_INTRBYTES, "intrbytes", KSTAT_DATA_UINT64, 0},
202 { MAC_STAT_POLLS, "polls", KSTAT_DATA_UINT64, 0},
203 { MAC_STAT_POLLBYTES, "pollbytes", KSTAT_DATA_UINT64, 0},
204 { MAC_STAT_RXSDROPS, "rxsdrops", KSTAT_DATA_UINT64, 0},
205 { MAC_STAT_CHU10, "chainunder10", KSTAT_DATA_UINT64, 0},
206 { MAC_STAT_CH10T50, "chain10to50", KSTAT_DATA_UINT64, 0},
207 { MAC_STAT_CHO50, "chainover50", KSTAT_DATA_UINT64, 0},
208 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT64, 0},
209 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT64, 0},
210 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT64, 0},
211 { MAC_STAT_BLOCK, "blockcnt", KSTAT_DATA_UINT64, 0},
212 { MAC_STAT_UNBLOCK, "unblockcnt", KSTAT_DATA_UINT64, 0},
213 { MAC_STAT_TXSDROPS, "txsdrops", KSTAT_DATA_UINT64, 0}
214 };
215 #define MAC_SUMMARY_NKSTAT \
216 (sizeof (i_mac_misc_si) / sizeof (mac_stat_info_t))
217
218 /*
219 * Definitions for per hardware lane tx statistics
220 */
221 static mac_stat_info_t i_mac_tx_hwlane_si[] = {
222 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT64, 0},
223 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT64, 0},
224 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT64, 0},
225 { MAC_STAT_BLOCK, "blockcnt", KSTAT_DATA_UINT64, 0},
226 { MAC_STAT_UNBLOCK, "unblockcnt", KSTAT_DATA_UINT64, 0},
227 { MAC_STAT_TXSDROPS, "txsdrops", KSTAT_DATA_UINT64, 0}
228 };
229 #define MAC_TX_HWLANE_NKSTAT \
230 (sizeof (i_mac_tx_hwlane_si) / sizeof (mac_stat_info_t))
231
232 /*
233 * Definitions for per fanout rx statistics
234 */
235 static mac_stat_info_t i_mac_rx_fanout_si[] = {
236 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT64, 0},
237 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT64, 0},
238 };
239 #define MAC_RX_FANOUT_NKSTAT \
240 (sizeof (i_mac_rx_fanout_si) / sizeof (mac_stat_info_t))
241
242 /*
243 * Private functions.
244 */
245
246 typedef struct {
247 uint_t si_offset;
248 } stat_info_t;
249
250 #define RX_SRS_STAT_OFF(f) (offsetof(mac_rx_stats_t, f))
251 static stat_info_t rx_srs_stats_list[] = {
252 {RX_SRS_STAT_OFF(mrs_lclbytes)},
253 {RX_SRS_STAT_OFF(mrs_lclcnt)},
254 {RX_SRS_STAT_OFF(mrs_pollcnt)},
255 {RX_SRS_STAT_OFF(mrs_pollbytes)},
256 {RX_SRS_STAT_OFF(mrs_intrcnt)},
257 {RX_SRS_STAT_OFF(mrs_intrbytes)},
258 {RX_SRS_STAT_OFF(mrs_sdrops)},
259 {RX_SRS_STAT_OFF(mrs_chaincntundr10)},
260 {RX_SRS_STAT_OFF(mrs_chaincnt10to50)},
261 {RX_SRS_STAT_OFF(mrs_chaincntover50)},
262 {RX_SRS_STAT_OFF(mrs_ierrors)}
263 };
264 #define RX_SRS_STAT_SIZE \
265 (sizeof (rx_srs_stats_list) / sizeof (stat_info_t))
266
267 #define TX_SOFTRING_STAT_OFF(f) (offsetof(mac_tx_stats_t, f))
268 static stat_info_t tx_softring_stats_list[] = {
269 {TX_SOFTRING_STAT_OFF(mts_obytes)},
270 {TX_SOFTRING_STAT_OFF(mts_opackets)},
271 {TX_SOFTRING_STAT_OFF(mts_oerrors)},
272 {TX_SOFTRING_STAT_OFF(mts_blockcnt)},
273 {TX_SOFTRING_STAT_OFF(mts_unblockcnt)},
274 {TX_SOFTRING_STAT_OFF(mts_sdrops)},
275 };
276 #define TX_SOFTRING_STAT_SIZE \
277 (sizeof (tx_softring_stats_list) / sizeof (stat_info_t))
278
279 static void
i_mac_add_stats(void * sum,void * op1,void * op2,stat_info_t stats_list[],uint_t size)280 i_mac_add_stats(void *sum, void *op1, void *op2,
281 stat_info_t stats_list[], uint_t size)
282 {
283 int i;
284
285 for (i = 0; i < size; i++) {
286 uint64_t *op1_val = (uint64_t *)
287 ((uchar_t *)op1 + stats_list[i].si_offset);
288 uint64_t *op2_val = (uint64_t *)
289 ((uchar_t *)op2 + stats_list[i].si_offset);
290 uint64_t *sum_val = (uint64_t *)
291 ((uchar_t *)sum + stats_list[i].si_offset);
292
293 *sum_val = *op1_val + *op2_val;
294 }
295 }
296
297 static int
i_mac_driver_stat_update(kstat_t * ksp,int rw)298 i_mac_driver_stat_update(kstat_t *ksp, int rw)
299 {
300 mac_impl_t *mip = ksp->ks_private;
301 kstat_named_t *knp = ksp->ks_data;
302 uint_t i;
303 uint64_t val;
304 mac_stat_info_t *msi;
305 uint_t msi_index;
306
307 if (rw != KSTAT_READ)
308 return (EACCES);
309
310 for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) {
311 if (i == MAC_MOD_KSTAT_OFFSET) {
312 msi_index = 0;
313 msi = i_mac_mod_si;
314 } else if (i == MAC_KSTAT_OFFSET) {
315 msi_index = 0;
316 msi = i_mac_si;
317 } else if (i == MAC_TYPE_KSTAT_OFFSET) {
318 msi_index = 0;
319 msi = mip->mi_type->mt_stats;
320 }
321
322 val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat);
323 switch (msi[msi_index].msi_type) {
324 case KSTAT_DATA_UINT64:
325 knp->value.ui64 = val;
326 break;
327 case KSTAT_DATA_UINT32:
328 knp->value.ui32 = (uint32_t)val;
329 break;
330 default:
331 ASSERT(B_FALSE);
332 break;
333 }
334
335 knp++;
336 }
337
338 return (0);
339 }
340
341 static void
i_mac_kstat_init(kstat_named_t * knp,mac_stat_info_t * si,uint_t count)342 i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count)
343 {
344 int i;
345 for (i = 0; i < count; i++) {
346 kstat_named_init(knp, si[i].msi_name, si[i].msi_type);
347 knp++;
348 }
349 }
350
351 static int
i_mac_stat_update(kstat_t * ksp,int rw,uint64_t (* fn)(void *,uint_t),mac_stat_info_t * msi,uint_t count)352 i_mac_stat_update(kstat_t *ksp, int rw, uint64_t (*fn)(void *, uint_t),
353 mac_stat_info_t *msi, uint_t count)
354 {
355 kstat_named_t *knp = ksp->ks_data;
356 uint_t i;
357 uint64_t val;
358
359 if (rw != KSTAT_READ)
360 return (EACCES);
361
362 for (i = 0; i < count; i++) {
363 val = fn(ksp->ks_private, msi[i].msi_stat);
364
365 switch (msi[i].msi_type) {
366 case KSTAT_DATA_UINT64:
367 knp->value.ui64 = val;
368 break;
369 case KSTAT_DATA_UINT32:
370 knp->value.ui32 = (uint32_t)val;
371 break;
372 default:
373 ASSERT(B_FALSE);
374 break;
375 }
376 knp++;
377 }
378 return (0);
379 }
380
381 /*
382 * Create kstat with given name - statname, update function - fn
383 * and initialize it with given names - init_stat_info
384 */
385 static kstat_t *
i_mac_stat_create(void * handle,const char * modname,const char * statname,int (* fn)(kstat_t *,int),mac_stat_info_t * init_stat_info,uint_t count)386 i_mac_stat_create(void *handle, const char *modname, const char *statname,
387 int (*fn) (kstat_t *, int),
388 mac_stat_info_t *init_stat_info, uint_t count)
389 {
390 kstat_t *ksp;
391 kstat_named_t *knp;
392
393 ksp = kstat_create(modname, 0, statname, "net",
394 KSTAT_TYPE_NAMED, count, 0);
395
396 if (ksp == NULL)
397 return (NULL);
398
399 ksp->ks_update = fn;
400 ksp->ks_private = handle;
401
402 knp = (kstat_named_t *)ksp->ks_data;
403 i_mac_kstat_init(knp, init_stat_info, count);
404 kstat_install(ksp);
405
406 return (ksp);
407 }
408
409 /*
410 * Per rx ring statistics
411 */
412 uint64_t
mac_rx_ring_stat_get(void * handle,uint_t stat)413 mac_rx_ring_stat_get(void *handle, uint_t stat)
414 {
415 mac_ring_t *ring = (mac_ring_t *)handle;
416 uint64_t val = 0;
417
418 /*
419 * XXX Every ring-capable driver must implement an entry point to
420 * query per ring statistics. CR 6893122 tracks this work item.
421 * Once this bug is fixed, the framework should fail registration
422 * for a driver that does not implement this entry point and
423 * assert ring->mr_stat != NULL here.
424 */
425 if (ring->mr_stat != NULL)
426 ring->mr_stat(ring->mr_driver, stat, &val);
427
428 return (val);
429 }
430
431 static int
i_mac_rx_ring_stat_update(kstat_t * ksp,int rw)432 i_mac_rx_ring_stat_update(kstat_t *ksp, int rw)
433 {
434 return (i_mac_stat_update(ksp, rw, mac_rx_ring_stat_get,
435 i_mac_rx_ring_si, MAC_RX_RING_NKSTAT));
436 }
437
438 static void
i_mac_rx_ring_stat_create(mac_ring_t * ring,const char * modname,const char * statname)439 i_mac_rx_ring_stat_create(mac_ring_t *ring, const char *modname,
440 const char *statname)
441 {
442 kstat_t *ksp;
443
444 ksp = i_mac_stat_create(ring, modname, statname,
445 i_mac_rx_ring_stat_update, i_mac_rx_ring_si, MAC_RX_RING_NKSTAT);
446
447 ring->mr_ksp = ksp;
448 }
449
450 /*
451 * Per tx ring statistics
452 */
453 uint64_t
mac_tx_ring_stat_get(void * handle,uint_t stat)454 mac_tx_ring_stat_get(void *handle, uint_t stat)
455 {
456 mac_ring_t *ring = (mac_ring_t *)handle;
457 uint64_t val = 0;
458
459 /*
460 * XXX Every ring-capable driver must implement an entry point to
461 * query per ring statistics. CR 6893122 tracks this work item.
462 * Once this bug is fixed, the framework should fail registration
463 * for a driver that does not implement this entry point and
464 * assert ring->mr_stat != NULL here.
465 */
466 if (ring->mr_stat != NULL)
467 ring->mr_stat(ring->mr_driver, stat, &val);
468
469 return (val);
470 }
471
472 static int
i_mac_tx_ring_stat_update(kstat_t * ksp,int rw)473 i_mac_tx_ring_stat_update(kstat_t *ksp, int rw)
474 {
475 return (i_mac_stat_update(ksp, rw, mac_tx_ring_stat_get,
476 i_mac_tx_ring_si, MAC_TX_RING_NKSTAT));
477 }
478
479 static void
i_mac_tx_ring_stat_create(mac_ring_t * ring,const char * modname,const char * statname)480 i_mac_tx_ring_stat_create(mac_ring_t *ring, const char *modname,
481 const char *statname)
482 {
483 kstat_t *ksp;
484
485 ksp = i_mac_stat_create(ring, modname, statname,
486 i_mac_tx_ring_stat_update, i_mac_tx_ring_si, MAC_TX_RING_NKSTAT);
487
488 ring->mr_ksp = ksp;
489 }
490
491 /*
492 * Per software lane tx statistics
493 */
494 static uint64_t
i_mac_tx_swlane_stat_get(void * handle,uint_t stat)495 i_mac_tx_swlane_stat_get(void *handle, uint_t stat)
496 {
497 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)handle;
498 mac_tx_stats_t *mac_tx_stat = &mac_srs->srs_tx.st_stat;
499
500 switch (stat) {
501 case MAC_STAT_OBYTES:
502 return (mac_tx_stat->mts_obytes);
503
504 case MAC_STAT_OPACKETS:
505 return (mac_tx_stat->mts_opackets);
506
507 case MAC_STAT_OERRORS:
508 return (mac_tx_stat->mts_oerrors);
509
510 case MAC_STAT_BLOCK:
511 return (mac_tx_stat->mts_blockcnt);
512
513 case MAC_STAT_UNBLOCK:
514 return (mac_tx_stat->mts_unblockcnt);
515
516 case MAC_STAT_TXSDROPS:
517 return (mac_tx_stat->mts_sdrops);
518
519 default:
520 return (0);
521 }
522 }
523
524 static int
i_mac_tx_swlane_stat_update(kstat_t * ksp,int rw)525 i_mac_tx_swlane_stat_update(kstat_t *ksp, int rw)
526 {
527 return (i_mac_stat_update(ksp, rw, i_mac_tx_swlane_stat_get,
528 i_mac_tx_swlane_si, MAC_TX_SWLANE_NKSTAT));
529 }
530
531 static void
i_mac_tx_swlane_stat_create(mac_soft_ring_set_t * mac_srs,const char * modname,const char * statname)532 i_mac_tx_swlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
533 const char *statname)
534 {
535 kstat_t *ksp;
536
537 ksp = i_mac_stat_create(mac_srs, modname, statname,
538 i_mac_tx_swlane_stat_update, i_mac_tx_swlane_si,
539 MAC_TX_SWLANE_NKSTAT);
540
541 mac_srs->srs_ksp = ksp;
542 }
543
544 /*
545 * Per software lane rx statistics
546 */
547 static uint64_t
i_mac_rx_swlane_stat_get(void * handle,uint_t stat)548 i_mac_rx_swlane_stat_get(void *handle, uint_t stat)
549 {
550 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)handle;
551 mac_rx_stats_t *mac_rx_stat = &mac_srs->srs_rx.sr_stat;
552
553 switch (stat) {
554 case MAC_STAT_IPACKETS:
555 return (mac_rx_stat->mrs_intrcnt +
556 mac_rx_stat->mrs_lclcnt);
557
558 case MAC_STAT_RBYTES:
559 return (mac_rx_stat->mrs_intrbytes +
560 mac_rx_stat->mrs_lclbytes);
561
562 case MAC_STAT_LCL:
563 return (mac_rx_stat->mrs_lclcnt);
564
565 case MAC_STAT_LCLBYTES:
566 return (mac_rx_stat->mrs_lclbytes);
567
568 case MAC_STAT_INTRS:
569 return (mac_rx_stat->mrs_intrcnt);
570
571 case MAC_STAT_INTRBYTES:
572 return (mac_rx_stat->mrs_intrbytes);
573
574 case MAC_STAT_RXSDROPS:
575 return (mac_rx_stat->mrs_sdrops);
576
577 default:
578 return (0);
579 }
580 }
581
582 static int
i_mac_rx_swlane_stat_update(kstat_t * ksp,int rw)583 i_mac_rx_swlane_stat_update(kstat_t *ksp, int rw)
584 {
585 return (i_mac_stat_update(ksp, rw, i_mac_rx_swlane_stat_get,
586 i_mac_rx_swlane_si, MAC_RX_SWLANE_NKSTAT));
587 }
588
589 static void
i_mac_rx_swlane_stat_create(mac_soft_ring_set_t * mac_srs,const char * modname,const char * statname)590 i_mac_rx_swlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
591 const char *statname)
592 {
593 kstat_t *ksp;
594
595 ksp = i_mac_stat_create(mac_srs, modname, statname,
596 i_mac_rx_swlane_stat_update, i_mac_rx_swlane_si,
597 MAC_RX_SWLANE_NKSTAT);
598
599 mac_srs->srs_ksp = ksp;
600 }
601
602
603 /*
604 * Per hardware lane rx statistics
605 */
606 static uint64_t
i_mac_rx_hwlane_stat_get(void * handle,uint_t stat)607 i_mac_rx_hwlane_stat_get(void *handle, uint_t stat)
608 {
609 mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)handle;
610 mac_rx_stats_t *mac_rx_stat = &mac_srs->srs_rx.sr_stat;
611
612 switch (stat) {
613 case MAC_STAT_IPACKETS:
614 return (mac_rx_stat->mrs_intrcnt +
615 mac_rx_stat->mrs_pollcnt);
616
617 case MAC_STAT_RBYTES:
618 return (mac_rx_stat->mrs_intrbytes +
619 mac_rx_stat->mrs_pollbytes);
620
621 case MAC_STAT_INTRS:
622 return (mac_rx_stat->mrs_intrcnt);
623
624 case MAC_STAT_INTRBYTES:
625 return (mac_rx_stat->mrs_intrbytes);
626
627 case MAC_STAT_POLLS:
628 return (mac_rx_stat->mrs_pollcnt);
629
630 case MAC_STAT_POLLBYTES:
631 return (mac_rx_stat->mrs_pollbytes);
632
633 case MAC_STAT_RXSDROPS:
634 return (mac_rx_stat->mrs_sdrops);
635
636 case MAC_STAT_CHU10:
637 return (mac_rx_stat->mrs_chaincntundr10);
638
639 case MAC_STAT_CH10T50:
640 return (mac_rx_stat->mrs_chaincnt10to50);
641
642 case MAC_STAT_CHO50:
643 return (mac_rx_stat->mrs_chaincntover50);
644
645 default:
646 return (0);
647 }
648 }
649
650 static int
i_mac_rx_hwlane_stat_update(kstat_t * ksp,int rw)651 i_mac_rx_hwlane_stat_update(kstat_t *ksp, int rw)
652 {
653 return (i_mac_stat_update(ksp, rw, i_mac_rx_hwlane_stat_get,
654 i_mac_rx_hwlane_si, MAC_RX_HWLANE_NKSTAT));
655 }
656
657 static void
i_mac_rx_hwlane_stat_create(mac_soft_ring_set_t * mac_srs,const char * modname,const char * statname)658 i_mac_rx_hwlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
659 const char *statname)
660 {
661 kstat_t *ksp;
662
663 ksp = i_mac_stat_create(mac_srs, modname, statname,
664 i_mac_rx_hwlane_stat_update, i_mac_rx_hwlane_si,
665 MAC_RX_HWLANE_NKSTAT);
666
667 mac_srs->srs_ksp = ksp;
668 }
669
670
671 /*
672 * Misc statistics
673 *
674 * Counts for
675 * - Multicast/broadcast Rx/Tx counts
676 * - Tx errors
677 */
678 static uint64_t
i_mac_misc_stat_get(void * handle,uint_t stat)679 i_mac_misc_stat_get(void *handle, uint_t stat)
680 {
681 flow_entry_t *flent = handle;
682 mac_client_impl_t *mcip = flent->fe_mcip;
683 mac_misc_stats_t *mac_misc_stat = &mcip->mci_misc_stat;
684 mac_rx_stats_t *mac_rx_stat;
685 mac_tx_stats_t *mac_tx_stat;
686
687 mac_rx_stat = &mac_misc_stat->mms_defunctrxlanestats;
688 mac_tx_stat = &mac_misc_stat->mms_defuncttxlanestats;
689
690 switch (stat) {
691 case MAC_STAT_MULTIRCV:
692 return (mac_misc_stat->mms_multircv);
693
694 case MAC_STAT_BRDCSTRCV:
695 return (mac_misc_stat->mms_brdcstrcv);
696
697 case MAC_STAT_MULTIXMT:
698 return (mac_misc_stat->mms_multixmt);
699
700 case MAC_STAT_BRDCSTXMT:
701 return (mac_misc_stat->mms_brdcstxmt);
702
703 case MAC_STAT_MULTIRCVBYTES:
704 return (mac_misc_stat->mms_multircvbytes);
705
706 case MAC_STAT_BRDCSTRCVBYTES:
707 return (mac_misc_stat->mms_brdcstrcvbytes);
708
709 case MAC_STAT_MULTIXMTBYTES:
710 return (mac_misc_stat->mms_multixmtbytes);
711
712 case MAC_STAT_BRDCSTXMTBYTES:
713 return (mac_misc_stat->mms_brdcstxmtbytes);
714
715 case MAC_STAT_TX_ERRORS:
716 return (mac_misc_stat->mms_txerrors);
717
718 case MAC_STAT_MACSPOOFED:
719 return (mac_misc_stat->mms_macspoofed);
720
721 case MAC_STAT_IPSPOOFED:
722 return (mac_misc_stat->mms_ipspoofed);
723
724 case MAC_STAT_DHCPSPOOFED:
725 return (mac_misc_stat->mms_dhcpspoofed);
726
727 case MAC_STAT_RESTRICTED:
728 return (mac_misc_stat->mms_restricted);
729
730 case MAC_STAT_DHCPDROPPED:
731 return (mac_misc_stat->mms_dhcpdropped);
732
733 case MAC_STAT_IPACKETS:
734 return (mac_rx_stat->mrs_intrcnt +
735 mac_rx_stat->mrs_pollcnt);
736
737 case MAC_STAT_RBYTES:
738 return (mac_rx_stat->mrs_intrbytes +
739 mac_rx_stat->mrs_pollbytes);
740
741 case MAC_STAT_LCL:
742 return (mac_rx_stat->mrs_lclcnt);
743
744 case MAC_STAT_LCLBYTES:
745 return (mac_rx_stat->mrs_lclbytes);
746
747 case MAC_STAT_INTRS:
748 return (mac_rx_stat->mrs_intrcnt);
749
750 case MAC_STAT_INTRBYTES:
751 return (mac_rx_stat->mrs_intrbytes);
752
753 case MAC_STAT_POLLS:
754 return (mac_rx_stat->mrs_pollcnt);
755
756 case MAC_STAT_POLLBYTES:
757 return (mac_rx_stat->mrs_pollbytes);
758
759 case MAC_STAT_RXSDROPS:
760 return (mac_rx_stat->mrs_sdrops);
761
762 case MAC_STAT_CHU10:
763 return (mac_rx_stat->mrs_chaincntundr10);
764
765 case MAC_STAT_CH10T50:
766 return (mac_rx_stat->mrs_chaincnt10to50);
767
768 case MAC_STAT_CHO50:
769 return (mac_rx_stat->mrs_chaincntover50);
770
771 case MAC_STAT_OBYTES:
772 return (mac_tx_stat->mts_obytes);
773
774 case MAC_STAT_OPACKETS:
775 return (mac_tx_stat->mts_opackets);
776
777 case MAC_STAT_OERRORS:
778 return (mac_tx_stat->mts_oerrors);
779
780 case MAC_STAT_BLOCK:
781 return (mac_tx_stat->mts_blockcnt);
782
783 case MAC_STAT_UNBLOCK:
784 return (mac_tx_stat->mts_unblockcnt);
785
786 case MAC_STAT_TXSDROPS:
787 return (mac_tx_stat->mts_sdrops);
788
789 default:
790 return (0);
791 }
792 }
793
794 static int
i_mac_misc_stat_update(kstat_t * ksp,int rw)795 i_mac_misc_stat_update(kstat_t *ksp, int rw)
796 {
797 return (i_mac_stat_update(ksp, rw, i_mac_misc_stat_get,
798 i_mac_misc_si, MAC_SUMMARY_NKSTAT));
799 }
800
801 static void
i_mac_misc_stat_create(flow_entry_t * flent,const char * modname,const char * statname)802 i_mac_misc_stat_create(flow_entry_t *flent, const char *modname,
803 const char *statname)
804 {
805 kstat_t *ksp;
806
807 ksp = i_mac_stat_create(flent, modname, statname,
808 i_mac_misc_stat_update, i_mac_misc_si,
809 MAC_SUMMARY_NKSTAT);
810
811 flent->fe_misc_stat_ksp = ksp;
812 }
813
814 /*
815 * Per hardware lane tx statistics
816 */
817 static uint64_t
i_mac_tx_hwlane_stat_get(void * handle,uint_t stat)818 i_mac_tx_hwlane_stat_get(void *handle, uint_t stat)
819 {
820 mac_soft_ring_t *ringp = (mac_soft_ring_t *)handle;
821 mac_tx_stats_t *mac_tx_stat = &ringp->s_st_stat;
822
823 switch (stat) {
824 case MAC_STAT_OBYTES:
825 return (mac_tx_stat->mts_obytes);
826
827 case MAC_STAT_OPACKETS:
828 return (mac_tx_stat->mts_opackets);
829
830 case MAC_STAT_OERRORS:
831 return (mac_tx_stat->mts_oerrors);
832
833 case MAC_STAT_BLOCK:
834 return (mac_tx_stat->mts_blockcnt);
835
836 case MAC_STAT_UNBLOCK:
837 return (mac_tx_stat->mts_unblockcnt);
838
839 case MAC_STAT_TXSDROPS:
840 return (mac_tx_stat->mts_sdrops);
841
842 default:
843 return (0);
844 }
845 }
846
847 static int
i_mac_tx_hwlane_stat_update(kstat_t * ksp,int rw)848 i_mac_tx_hwlane_stat_update(kstat_t *ksp, int rw)
849 {
850 return (i_mac_stat_update(ksp, rw, i_mac_tx_hwlane_stat_get,
851 i_mac_tx_hwlane_si, MAC_TX_HWLANE_NKSTAT));
852 }
853
854 static void
i_mac_tx_hwlane_stat_create(mac_soft_ring_t * ringp,const char * modname,const char * statname)855 i_mac_tx_hwlane_stat_create(mac_soft_ring_t *ringp, const char *modname,
856 const char *statname)
857 {
858 kstat_t *ksp;
859
860 ksp = i_mac_stat_create(ringp, modname, statname,
861 i_mac_tx_hwlane_stat_update, i_mac_tx_hwlane_si,
862 MAC_TX_HWLANE_NKSTAT);
863
864 ringp->s_ring_ksp = ksp;
865 }
866
867 /*
868 * Per fanout rx statistics
869 */
870 static uint64_t
i_mac_rx_fanout_stat_get(void * handle,uint_t stat)871 i_mac_rx_fanout_stat_get(void *handle, uint_t stat)
872 {
873 mac_soft_ring_t *tcp_ringp = (mac_soft_ring_t *)handle;
874 mac_soft_ring_t *udp_ringp = NULL, *oth_ringp = NULL;
875 mac_soft_ring_set_t *mac_srs = tcp_ringp->s_ring_set;
876 int index;
877 uint64_t val;
878
879 mutex_enter(&mac_srs->srs_lock);
880 /* Extract corresponding udp and oth ring pointers */
881 for (index = 0; mac_srs->srs_tcp_soft_rings[index] != NULL; index++) {
882 if (mac_srs->srs_tcp_soft_rings[index] == tcp_ringp) {
883 udp_ringp = mac_srs->srs_udp_soft_rings[index];
884 oth_ringp = mac_srs->srs_oth_soft_rings[index];
885 break;
886 }
887 }
888
889 ASSERT((udp_ringp != NULL) && (oth_ringp != NULL));
890
891 switch (stat) {
892 case MAC_STAT_RBYTES:
893 val = (tcp_ringp->s_ring_total_rbytes) +
894 (udp_ringp->s_ring_total_rbytes) +
895 (oth_ringp->s_ring_total_rbytes);
896 break;
897
898 case MAC_STAT_IPACKETS:
899 val = (tcp_ringp->s_ring_total_inpkt) +
900 (udp_ringp->s_ring_total_inpkt) +
901 (oth_ringp->s_ring_total_inpkt);
902 break;
903
904 default:
905 val = 0;
906 break;
907 }
908 mutex_exit(&mac_srs->srs_lock);
909 return (val);
910 }
911
912 static int
i_mac_rx_fanout_stat_update(kstat_t * ksp,int rw)913 i_mac_rx_fanout_stat_update(kstat_t *ksp, int rw)
914 {
915 return (i_mac_stat_update(ksp, rw, i_mac_rx_fanout_stat_get,
916 i_mac_rx_fanout_si, MAC_RX_FANOUT_NKSTAT));
917 }
918
919 static void
i_mac_rx_fanout_stat_create(mac_soft_ring_t * ringp,const char * modname,const char * statname)920 i_mac_rx_fanout_stat_create(mac_soft_ring_t *ringp, const char *modname,
921 const char *statname)
922 {
923 kstat_t *ksp;
924
925 ksp = i_mac_stat_create(ringp, modname, statname,
926 i_mac_rx_fanout_stat_update, i_mac_rx_fanout_si,
927 MAC_RX_FANOUT_NKSTAT);
928
929 ringp->s_ring_ksp = ksp;
930 }
931
932 /*
933 * Exported functions.
934 */
935
936 /*
937 * Create the "mac" kstat. The "mac" kstat is comprised of three kinds of
938 * statistics: statistics maintained by the mac module itself, generic mac
939 * statistics maintained by the driver, and MAC-type specific statistics
940 * also maintained by the driver.
941 */
942 void
mac_driver_stat_create(mac_impl_t * mip)943 mac_driver_stat_create(mac_impl_t *mip)
944 {
945 kstat_t *ksp;
946 kstat_named_t *knp;
947 uint_t count;
948 major_t major = getmajor(mip->mi_phy_dev);
949
950 count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount;
951 ksp = kstat_create((const char *)ddi_major_to_name(major),
952 getminor(mip->mi_phy_dev) - 1, MAC_KSTAT_NAME,
953 MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0);
954 if (ksp == NULL)
955 return;
956
957 ksp->ks_update = i_mac_driver_stat_update;
958 ksp->ks_private = mip;
959 mip->mi_ksp = ksp;
960 mip->mi_kstat_count = count;
961
962 knp = (kstat_named_t *)ksp->ks_data;
963 i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT);
964 knp += MAC_MOD_NKSTAT;
965 i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT);
966 if (mip->mi_type->mt_statcount > 0) {
967 knp += MAC_NKSTAT;
968 i_mac_kstat_init(knp, mip->mi_type->mt_stats,
969 mip->mi_type->mt_statcount);
970 }
971
972 kstat_install(ksp);
973 }
974
975 /*ARGSUSED*/
976 void
mac_driver_stat_delete(mac_impl_t * mip)977 mac_driver_stat_delete(mac_impl_t *mip)
978 {
979 if (mip->mi_ksp != NULL) {
980 kstat_delete(mip->mi_ksp);
981 mip->mi_ksp = NULL;
982 mip->mi_kstat_count = 0;
983 }
984 }
985
986 uint64_t
mac_driver_stat_default(mac_impl_t * mip,uint_t stat)987 mac_driver_stat_default(mac_impl_t *mip, uint_t stat)
988 {
989 uint_t stat_index;
990
991 if (IS_MAC_STAT(stat)) {
992 stat_index = stat - MAC_STAT_MIN;
993 ASSERT(stat_index < MAC_NKSTAT);
994 return (i_mac_si[stat_index].msi_default);
995 }
996 ASSERT(IS_MACTYPE_STAT(stat));
997 stat_index = stat - MACTYPE_STAT_MIN;
998 ASSERT(stat_index < mip->mi_type->mt_statcount);
999 return (mip->mi_type->mt_stats[stat_index].msi_default);
1000 }
1001
1002 void
mac_ring_stat_create(mac_ring_t * ring)1003 mac_ring_stat_create(mac_ring_t *ring)
1004 {
1005 mac_impl_t *mip = ring->mr_mip;
1006 char statname[MAXNAMELEN];
1007 char modname[MAXNAMELEN];
1008
1009 if (mip->mi_state_flags & MIS_IS_AGGR) {
1010 (void) strlcpy(modname, mip->mi_clients_list->mci_name,
1011 MAXNAMELEN);
1012 } else
1013 (void) strlcpy(modname, mip->mi_name, MAXNAMELEN);
1014
1015 switch (ring->mr_type) {
1016 case MAC_RING_TYPE_RX:
1017 (void) snprintf(statname, sizeof (statname), "mac_rx_ring%d",
1018 ring->mr_index);
1019 i_mac_rx_ring_stat_create(ring, modname, statname);
1020 break;
1021
1022 case MAC_RING_TYPE_TX:
1023 (void) snprintf(statname, sizeof (statname), "mac_tx_ring%d",
1024 ring->mr_index);
1025 i_mac_tx_ring_stat_create(ring, modname, statname);
1026 break;
1027
1028 default:
1029 ASSERT(B_FALSE);
1030 break;
1031 }
1032 }
1033
1034 void
mac_srs_stat_create(mac_soft_ring_set_t * mac_srs)1035 mac_srs_stat_create(mac_soft_ring_set_t *mac_srs)
1036 {
1037 flow_entry_t *flent = mac_srs->srs_flent;
1038 char statname[MAXNAMELEN];
1039 boolean_t is_tx_srs;
1040
1041 /* No hardware/software lanes for user defined flows */
1042 if ((flent->fe_type & FLOW_USER) != 0)
1043 return;
1044
1045 is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1046
1047 if (is_tx_srs) {
1048 mac_srs_tx_t *srs_tx = &mac_srs->srs_tx;
1049 mac_ring_t *ring = srs_tx->st_arg2;
1050
1051 if (ring != NULL) {
1052 (void) snprintf(statname, sizeof (statname),
1053 "mac_tx_hwlane%d", ring->mr_index);
1054 } else {
1055 (void) snprintf(statname, sizeof (statname),
1056 "mac_tx_swlane0");
1057 }
1058 i_mac_tx_swlane_stat_create(mac_srs, flent->fe_flow_name,
1059 statname);
1060 } else {
1061 mac_ring_t *ring = mac_srs->srs_ring;
1062
1063 if (ring == NULL) {
1064 (void) snprintf(statname, sizeof (statname),
1065 "mac_rx_swlane0");
1066 i_mac_rx_swlane_stat_create(mac_srs,
1067 flent->fe_flow_name, statname);
1068 } else {
1069 (void) snprintf(statname, sizeof (statname),
1070 "mac_rx_hwlane%d", ring->mr_index);
1071 i_mac_rx_hwlane_stat_create(mac_srs,
1072 flent->fe_flow_name, statname);
1073 }
1074 }
1075 }
1076
1077 void
mac_misc_stat_create(flow_entry_t * flent)1078 mac_misc_stat_create(flow_entry_t *flent)
1079 {
1080 char statname[MAXNAMELEN];
1081
1082 /* No misc stats for user defined or mcast/bcast flows */
1083 if (((flent->fe_type & FLOW_USER) != 0) ||
1084 ((flent->fe_type & FLOW_MCAST) != 0))
1085 return;
1086
1087 (void) snprintf(statname, sizeof (statname), "mac_misc_stat");
1088 i_mac_misc_stat_create(flent, flent->fe_flow_name, statname);
1089 }
1090
1091 void
mac_soft_ring_stat_create(mac_soft_ring_t * ringp)1092 mac_soft_ring_stat_create(mac_soft_ring_t *ringp)
1093 {
1094 mac_soft_ring_set_t *mac_srs = ringp->s_ring_set;
1095 flow_entry_t *flent = ringp->s_ring_mcip->mci_flent;
1096 mac_ring_t *ring = (mac_ring_t *)ringp->s_ring_tx_arg2;
1097 boolean_t is_tx_srs;
1098 char statname[MAXNAMELEN];
1099
1100 /* No hardware/software lanes for user defined flows */
1101 if ((flent->fe_type & FLOW_USER) != 0)
1102 return;
1103
1104 is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1105 if (is_tx_srs) { /* tx side hardware lane */
1106 ASSERT(ring != NULL);
1107 (void) snprintf(statname, sizeof (statname), "mac_tx_hwlane%d",
1108 ring->mr_index);
1109 i_mac_tx_hwlane_stat_create(ringp, flent->fe_flow_name,
1110 statname);
1111 } else { /* rx side fanout */
1112 /* Maintain single stat for (tcp, udp, oth) */
1113 if (ringp->s_ring_type & ST_RING_TCP) {
1114 int index;
1115 mac_soft_ring_t *softring;
1116
1117 for (index = 0, softring = mac_srs->srs_soft_ring_head;
1118 softring != NULL;
1119 index++, softring = softring->s_ring_next) {
1120 if (softring == ringp)
1121 break;
1122 }
1123
1124 if (mac_srs->srs_ring == NULL) {
1125 (void) snprintf(statname, sizeof (statname),
1126 "mac_rx_swlane0_fanout%d", index/3);
1127 } else {
1128 (void) snprintf(statname, sizeof (statname),
1129 "mac_rx_hwlane%d_fanout%d",
1130 mac_srs->srs_ring->mr_index, index/3);
1131 }
1132 i_mac_rx_fanout_stat_create(ringp, flent->fe_flow_name,
1133 statname);
1134 }
1135 }
1136 }
1137
1138 void
mac_ring_stat_delete(mac_ring_t * ring)1139 mac_ring_stat_delete(mac_ring_t *ring)
1140 {
1141 if (ring->mr_ksp != NULL) {
1142 kstat_delete(ring->mr_ksp);
1143 ring->mr_ksp = NULL;
1144 }
1145 }
1146
1147 void
mac_srs_stat_delete(mac_soft_ring_set_t * mac_srs)1148 mac_srs_stat_delete(mac_soft_ring_set_t *mac_srs)
1149 {
1150 boolean_t is_tx_srs;
1151
1152 is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1153 if (!is_tx_srs) {
1154 /*
1155 * Rx ring has been taken away. Before destroying corresponding
1156 * SRS, save the stats recorded by that SRS.
1157 */
1158 mac_client_impl_t *mcip = mac_srs->srs_mcip;
1159 mac_misc_stats_t *mac_misc_stat = &mcip->mci_misc_stat;
1160 mac_rx_stats_t *mac_rx_stat = &mac_srs->srs_rx.sr_stat;
1161
1162 i_mac_add_stats(&mac_misc_stat->mms_defunctrxlanestats,
1163 mac_rx_stat, &mac_misc_stat->mms_defunctrxlanestats,
1164 rx_srs_stats_list, RX_SRS_STAT_SIZE);
1165 }
1166
1167 if (mac_srs->srs_ksp != NULL) {
1168 kstat_delete(mac_srs->srs_ksp);
1169 mac_srs->srs_ksp = NULL;
1170 }
1171 }
1172
1173 void
mac_misc_stat_delete(flow_entry_t * flent)1174 mac_misc_stat_delete(flow_entry_t *flent)
1175 {
1176 if (flent->fe_misc_stat_ksp != NULL) {
1177 kstat_delete(flent->fe_misc_stat_ksp);
1178 flent->fe_misc_stat_ksp = NULL;
1179 }
1180 }
1181
1182 void
mac_soft_ring_stat_delete(mac_soft_ring_t * ringp)1183 mac_soft_ring_stat_delete(mac_soft_ring_t *ringp)
1184 {
1185 mac_soft_ring_set_t *mac_srs = ringp->s_ring_set;
1186 boolean_t is_tx_srs;
1187
1188 is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1189 if (is_tx_srs) {
1190 /*
1191 * Tx ring has been taken away. Before destroying corresponding
1192 * soft ring, save the stats recorded by that soft ring.
1193 */
1194 mac_client_impl_t *mcip = mac_srs->srs_mcip;
1195 mac_misc_stats_t *mac_misc_stat = &mcip->mci_misc_stat;
1196 mac_tx_stats_t *mac_tx_stat = &ringp->s_st_stat;
1197
1198 i_mac_add_stats(&mac_misc_stat->mms_defuncttxlanestats,
1199 mac_tx_stat, &mac_misc_stat->mms_defuncttxlanestats,
1200 tx_softring_stats_list, TX_SOFTRING_STAT_SIZE);
1201 }
1202
1203 if (ringp->s_ring_ksp) {
1204 kstat_delete(ringp->s_ring_ksp);
1205 ringp->s_ring_ksp = NULL;
1206 }
1207 }
1208
1209 void
mac_pseudo_ring_stat_rename(mac_impl_t * mip)1210 mac_pseudo_ring_stat_rename(mac_impl_t *mip)
1211 {
1212 mac_group_t *group;
1213 mac_ring_t *ring;
1214
1215 /* Recreate pseudo rx ring kstats */
1216 for (group = mip->mi_rx_groups; group != NULL;
1217 group = group->mrg_next) {
1218 for (ring = group->mrg_rings; ring != NULL;
1219 ring = ring->mr_next) {
1220 mac_ring_stat_delete(ring);
1221 mac_ring_stat_create(ring);
1222 }
1223 }
1224
1225 /* Recreate pseudo tx ring kstats */
1226 for (group = mip->mi_tx_groups; group != NULL;
1227 group = group->mrg_next) {
1228 for (ring = group->mrg_rings; ring != NULL;
1229 ring = ring->mr_next) {
1230 mac_ring_stat_delete(ring);
1231 mac_ring_stat_create(ring);
1232 }
1233 }
1234 }
1235
1236 void
mac_stat_rename(mac_client_impl_t * mcip)1237 mac_stat_rename(mac_client_impl_t *mcip)
1238 {
1239 flow_entry_t *flent = mcip->mci_flent;
1240 mac_soft_ring_set_t *mac_srs;
1241 mac_soft_ring_t *ringp;
1242 int i, j;
1243
1244 ASSERT(flent != NULL);
1245
1246 /* Recreate rx SRSes kstats */
1247 for (i = 0; i < flent->fe_rx_srs_cnt; i++) {
1248 mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i];
1249 mac_srs_stat_delete(mac_srs);
1250 mac_srs_stat_create(mac_srs);
1251
1252 /* Recreate rx fanout kstats */
1253 for (j = 0; j < mac_srs->srs_tcp_ring_count; j++) {
1254 ringp = mac_srs->srs_tcp_soft_rings[j];
1255 mac_soft_ring_stat_delete(ringp);
1256 mac_soft_ring_stat_create(ringp);
1257 }
1258 }
1259
1260 /* Recreate tx SRS kstats */
1261 mac_srs = (mac_soft_ring_set_t *)flent->fe_tx_srs;
1262 mac_srs_stat_delete(mac_srs);
1263 mac_srs_stat_create(mac_srs);
1264
1265 /* Recreate tx sofring kstats */
1266 for (ringp = mac_srs->srs_soft_ring_head; ringp;
1267 ringp = ringp->s_ring_next) {
1268 mac_soft_ring_stat_delete(ringp);
1269 mac_soft_ring_stat_create(ringp);
1270 }
1271
1272 /* Recreate misc kstats */
1273 mac_misc_stat_delete(flent);
1274 mac_misc_stat_create(flent);
1275 }
1276
1277 void
mac_tx_srs_stat_recreate(mac_soft_ring_set_t * tx_srs,boolean_t add_stats)1278 mac_tx_srs_stat_recreate(mac_soft_ring_set_t *tx_srs, boolean_t add_stats)
1279 {
1280 mac_client_impl_t *mcip = tx_srs->srs_mcip;
1281 mac_misc_stats_t *mac_misc_stat = &mcip->mci_misc_stat;
1282 mac_tx_stats_t *mac_tx_stat = &tx_srs->srs_tx.st_stat;
1283
1284 if (add_stats) {
1285 /* Add the stats to cumulative stats */
1286 i_mac_add_stats(&mac_misc_stat->mms_defuncttxlanestats,
1287 mac_tx_stat, &mac_misc_stat->mms_defuncttxlanestats,
1288 tx_softring_stats_list, TX_SOFTRING_STAT_SIZE);
1289 }
1290
1291 bzero(mac_tx_stat, sizeof (mac_tx_stats_t));
1292 mac_srs_stat_delete(tx_srs);
1293 mac_srs_stat_create(tx_srs);
1294 }
1295