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