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