14d0e5007SSukumar Swaminathan /*
24d0e5007SSukumar Swaminathan  * CDDL HEADER START
34d0e5007SSukumar Swaminathan  *
44d0e5007SSukumar Swaminathan  * The contents of this file are subject to the terms of the
54d0e5007SSukumar Swaminathan  * Common Development and Distribution License (the "License").
64d0e5007SSukumar Swaminathan  * You may not use this file except in compliance with the License.
74d0e5007SSukumar Swaminathan  *
84d0e5007SSukumar Swaminathan  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94d0e5007SSukumar Swaminathan  * or http://www.opensolaris.org/os/licensing.
104d0e5007SSukumar Swaminathan  * See the License for the specific language governing permissions
114d0e5007SSukumar Swaminathan  * and limitations under the License.
124d0e5007SSukumar Swaminathan  *
134d0e5007SSukumar Swaminathan  * When distributing Covered Code, include this CDDL HEADER in each
144d0e5007SSukumar Swaminathan  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154d0e5007SSukumar Swaminathan  * If applicable, add the following below this CDDL HEADER, with the
164d0e5007SSukumar Swaminathan  * fields enclosed by brackets "[]" replaced with your own identifying
174d0e5007SSukumar Swaminathan  * information: Portions Copyright [yyyy] [name of copyright owner]
184d0e5007SSukumar Swaminathan  *
194d0e5007SSukumar Swaminathan  * CDDL HEADER END
204d0e5007SSukumar Swaminathan  */
214d0e5007SSukumar Swaminathan 
22*3abb112fSGarrett D'Amore /* Copyright © 2003-2011 Emulex. All rights reserved.  */
234d0e5007SSukumar Swaminathan 
244d0e5007SSukumar Swaminathan /*
254d0e5007SSukumar Swaminathan  * Source file containing the implementation of the driver statistics
264d0e5007SSukumar Swaminathan  * and related helper functions
274d0e5007SSukumar Swaminathan  */
284d0e5007SSukumar Swaminathan 
294d0e5007SSukumar Swaminathan #include <oce_impl.h>
304d0e5007SSukumar Swaminathan #include <oce_stat.h>
314d0e5007SSukumar Swaminathan #include <oce_buf.h>
324d0e5007SSukumar Swaminathan 
335b9d3151SSukumar Swaminathan int pow10[5] = {
345b9d3151SSukumar Swaminathan 	0,
355b9d3151SSukumar Swaminathan 	10,
365b9d3151SSukumar Swaminathan 	100,
375b9d3151SSukumar Swaminathan 	1000,
385b9d3151SSukumar Swaminathan 	10000
395b9d3151SSukumar Swaminathan };
405b9d3151SSukumar Swaminathan 
414d0e5007SSukumar Swaminathan /*
424d0e5007SSukumar Swaminathan  * function called by kstat to update the stats counters
434d0e5007SSukumar Swaminathan  *
444d0e5007SSukumar Swaminathan  * ksp - pointer to the kstats structure
454d0e5007SSukumar Swaminathan  * rw - flags defining read/write
464d0e5007SSukumar Swaminathan  *
474d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
484d0e5007SSukumar Swaminathan  */
494d0e5007SSukumar Swaminathan static int
oce_update_stats(kstat_t * ksp,int rw)504d0e5007SSukumar Swaminathan oce_update_stats(kstat_t *ksp, int rw)
514d0e5007SSukumar Swaminathan {
524d0e5007SSukumar Swaminathan 	struct oce_dev *dev;
534d0e5007SSukumar Swaminathan 	struct oce_stat *stats;
544d0e5007SSukumar Swaminathan 	struct rx_port_stats *port_stats;
554d0e5007SSukumar Swaminathan 	int ret;
564d0e5007SSukumar Swaminathan 
574d0e5007SSukumar Swaminathan 	if (rw == KSTAT_WRITE) {
584d0e5007SSukumar Swaminathan 		return (EACCES);
594d0e5007SSukumar Swaminathan 	}
604d0e5007SSukumar Swaminathan 
614d0e5007SSukumar Swaminathan 	dev = ksp->ks_private;
624d0e5007SSukumar Swaminathan 	stats = (struct oce_stat *)ksp->ks_data;
634d0e5007SSukumar Swaminathan 	port_stats = &dev->hw_stats->params.rsp.rx.port[dev->port_id];
644d0e5007SSukumar Swaminathan 
654d0e5007SSukumar Swaminathan 	mutex_enter(&dev->dev_lock);
664d0e5007SSukumar Swaminathan 	if (dev->suspended) {
674d0e5007SSukumar Swaminathan 		mutex_exit(&dev->dev_lock);
684d0e5007SSukumar Swaminathan 		return (EIO);
694d0e5007SSukumar Swaminathan 	}
708d738d7dSSukumar Swaminathan 	ret = oce_get_hw_stats(dev);
718d738d7dSSukumar Swaminathan 	if (ret != DDI_SUCCESS) {
728d738d7dSSukumar Swaminathan 		oce_log(dev, CE_WARN, MOD_CONFIG,
738d738d7dSSukumar Swaminathan 		    "Failed to get stats:%d", ret);
748d738d7dSSukumar Swaminathan 		mutex_exit(&dev->dev_lock);
758d738d7dSSukumar Swaminathan 		return (EIO);
764d0e5007SSukumar Swaminathan 	}
774d0e5007SSukumar Swaminathan 
784d0e5007SSukumar Swaminathan 	/* update the stats */
794d0e5007SSukumar Swaminathan 	stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd;
804d0e5007SSukumar Swaminathan 	stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd;
814d0e5007SSukumar Swaminathan 
824d0e5007SSukumar Swaminathan 	stats->rx_frames.value.ul = port_stats->rx_total_frames;
834d0e5007SSukumar Swaminathan 	stats->rx_errors.value.ul = port_stats->rx_crc_errors +
844d0e5007SSukumar Swaminathan 	    port_stats->rx_alignment_symbol_errors +
854d0e5007SSukumar Swaminathan 	    port_stats->rx_in_range_errors +
864d0e5007SSukumar Swaminathan 	    port_stats->rx_out_range_errors +
874d0e5007SSukumar Swaminathan 	    port_stats->rx_frame_too_long +
884d0e5007SSukumar Swaminathan 	    port_stats->rx_ip_checksum_errs +
894d0e5007SSukumar Swaminathan 	    port_stats->rx_tcp_checksum_errs +
904d0e5007SSukumar Swaminathan 	    port_stats->rx_udp_checksum_errs;
914d0e5007SSukumar Swaminathan 
924d0e5007SSukumar Swaminathan 	stats->rx_drops.value.ul = port_stats->rx_dropped_too_small +
934d0e5007SSukumar Swaminathan 	    port_stats->rx_dropped_too_short +
944d0e5007SSukumar Swaminathan 	    port_stats->rx_dropped_header_too_small +
954d0e5007SSukumar Swaminathan 	    port_stats->rx_dropped_tcp_length +
964d0e5007SSukumar Swaminathan 	    port_stats->rx_dropped_runt;
974d0e5007SSukumar Swaminathan 
984d0e5007SSukumar Swaminathan 	stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd;
994d0e5007SSukumar Swaminathan 	stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd;
1004d0e5007SSukumar Swaminathan 
1014d0e5007SSukumar Swaminathan 	stats->tx_frames.value.ul = port_stats->tx_unicast_frames +
1024d0e5007SSukumar Swaminathan 	    port_stats->tx_multicast_frames +
1034d0e5007SSukumar Swaminathan 	    port_stats->tx_broadcast_frames +
1044d0e5007SSukumar Swaminathan 	    port_stats->tx_pause_frames +
1054d0e5007SSukumar Swaminathan 	    port_stats->tx_control_frames;
1064d0e5007SSukumar Swaminathan 	stats->tx_errors.value.ul = dev->tx_errors;
1074d0e5007SSukumar Swaminathan 
1084d0e5007SSukumar Swaminathan 	stats->rx_unicast_frames.value.ul =
1094d0e5007SSukumar Swaminathan 	    port_stats->rx_unicast_frames;
1104d0e5007SSukumar Swaminathan 	stats->rx_multicast_frames.value.ul =
1114d0e5007SSukumar Swaminathan 	    port_stats->rx_multicast_frames;
1124d0e5007SSukumar Swaminathan 	stats->rx_broadcast_frames.value.ul =
1134d0e5007SSukumar Swaminathan 	    port_stats->rx_broadcast_frames;
1144d0e5007SSukumar Swaminathan 	stats->rx_crc_errors.value.ul =
1154d0e5007SSukumar Swaminathan 	    port_stats->rx_crc_errors;
1164d0e5007SSukumar Swaminathan 
1174d0e5007SSukumar Swaminathan 	stats->rx_alignment_symbol_errors.value.ul =
1184d0e5007SSukumar Swaminathan 	    port_stats->rx_alignment_symbol_errors;
1194d0e5007SSukumar Swaminathan 	stats->rx_in_range_errors.value.ul =
1204d0e5007SSukumar Swaminathan 	    port_stats->rx_in_range_errors;
1214d0e5007SSukumar Swaminathan 	stats->rx_out_range_errors.value.ul =
1224d0e5007SSukumar Swaminathan 	    port_stats->rx_out_range_errors;
1234d0e5007SSukumar Swaminathan 	stats->rx_frame_too_long.value.ul =
1244d0e5007SSukumar Swaminathan 	    port_stats->rx_frame_too_long;
1254d0e5007SSukumar Swaminathan 	stats->rx_address_match_errors.value.ul =
1264d0e5007SSukumar Swaminathan 	    port_stats->rx_address_match_errors;
1274d0e5007SSukumar Swaminathan 
1284d0e5007SSukumar Swaminathan 	stats->rx_pause_frames.value.ul =
1294d0e5007SSukumar Swaminathan 	    port_stats->rx_pause_frames;
1304d0e5007SSukumar Swaminathan 	stats->rx_control_frames.value.ul =
1314d0e5007SSukumar Swaminathan 	    port_stats->rx_control_frames;
1324d0e5007SSukumar Swaminathan 	stats->rx_ip_checksum_errs.value.ul =
1334d0e5007SSukumar Swaminathan 	    port_stats->rx_ip_checksum_errs;
1344d0e5007SSukumar Swaminathan 	stats->rx_tcp_checksum_errs.value.ul =
1354d0e5007SSukumar Swaminathan 	    port_stats->rx_tcp_checksum_errs;
1364d0e5007SSukumar Swaminathan 	stats->rx_udp_checksum_errs.value.ul =
1374d0e5007SSukumar Swaminathan 	    port_stats->rx_udp_checksum_errs;
1384d0e5007SSukumar Swaminathan 	stats->rx_fifo_overflow.value.ul = port_stats->rx_fifo_overflow;
1394d0e5007SSukumar Swaminathan 	stats->rx_input_fifo_overflow.value.ul =
1404d0e5007SSukumar Swaminathan 	    port_stats->rx_input_fifo_overflow;
1414d0e5007SSukumar Swaminathan 
1424d0e5007SSukumar Swaminathan 	stats->tx_unicast_frames.value.ul =
1434d0e5007SSukumar Swaminathan 	    port_stats->tx_unicast_frames;
1444d0e5007SSukumar Swaminathan 	stats->tx_multicast_frames.value.ul =
1454d0e5007SSukumar Swaminathan 	    port_stats->tx_multicast_frames;
1464d0e5007SSukumar Swaminathan 	stats->tx_broadcast_frames.value.ul =
1474d0e5007SSukumar Swaminathan 	    port_stats->tx_broadcast_frames;
1484d0e5007SSukumar Swaminathan 	stats->tx_pause_frames.value.ul =
1494d0e5007SSukumar Swaminathan 	    port_stats->tx_pause_frames;
1504d0e5007SSukumar Swaminathan 	stats->tx_control_frames.value.ul =
1514d0e5007SSukumar Swaminathan 	    port_stats->tx_control_frames;
152*3abb112fSGarrett D'Amore 
153*3abb112fSGarrett D'Amore 
154*3abb112fSGarrett D'Amore 	stats->rx_drops_no_pbuf.value.ul =
155*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_no_pbuf;
156*3abb112fSGarrett D'Amore 	stats->rx_drops_no_txpb.value.ul =
157*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_no_txpb;
158*3abb112fSGarrett D'Amore 	stats->rx_drops_no_erx_descr.value.ul =
159*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_no_erx_descr;
160*3abb112fSGarrett D'Amore 	stats->rx_drops_no_tpre_descr.value.ul =
161*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_no_tpre_descr;
162*3abb112fSGarrett D'Amore 	stats->rx_drops_too_many_frags.value.ul =
163*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_too_many_frags;
164*3abb112fSGarrett D'Amore 	stats->rx_drops_invalid_ring.value.ul =
165*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_invalid_ring;
166*3abb112fSGarrett D'Amore 	stats->rx_drops_mtu.value.ul =
167*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.rx.rx_drops_mtu;
168*3abb112fSGarrett D'Amore 
169*3abb112fSGarrett D'Amore 	stats->rx_dropped_too_small.value.ul =
170*3abb112fSGarrett D'Amore 	    port_stats->rx_dropped_too_small;
171*3abb112fSGarrett D'Amore 	stats->rx_dropped_too_short.value.ul =
172*3abb112fSGarrett D'Amore 	    port_stats->rx_dropped_too_short;
173*3abb112fSGarrett D'Amore 	stats->rx_dropped_header_too_small.value.ul =
174*3abb112fSGarrett D'Amore 	    port_stats->rx_dropped_header_too_small;
175*3abb112fSGarrett D'Amore 	stats->rx_dropped_tcp_length.value.ul =
176*3abb112fSGarrett D'Amore 	    port_stats->rx_dropped_tcp_length;
177*3abb112fSGarrett D'Amore 	stats->rx_dropped_runt.value.ul =
178*3abb112fSGarrett D'Amore 	    port_stats->rx_dropped_runt;
179*3abb112fSGarrett D'Amore 
180*3abb112fSGarrett D'Amore 	stats->rx_drops_no_fragments.value.ul =
181*3abb112fSGarrett D'Amore 	    dev->hw_stats->params.rsp.err_rx.rx_drops_no_fragments[0];
182*3abb112fSGarrett D'Amore 
1838d738d7dSSukumar Swaminathan 	mutex_exit(&dev->dev_lock);
1844d0e5007SSukumar Swaminathan 	return (DDI_SUCCESS);
1854d0e5007SSukumar Swaminathan } /* oce_update_stats */
1864d0e5007SSukumar Swaminathan 
1874d0e5007SSukumar Swaminathan /*
1884d0e5007SSukumar Swaminathan  * function to setup the kstat_t structure for the device and install it
1894d0e5007SSukumar Swaminathan  *
1904d0e5007SSukumar Swaminathan  * dev - software handle to the device
1914d0e5007SSukumar Swaminathan  *
1924d0e5007SSukumar Swaminathan  * return DDI_SUCCESS => success, failure otherwise
1934d0e5007SSukumar Swaminathan  */
1944d0e5007SSukumar Swaminathan int
oce_stat_init(struct oce_dev * dev)1954d0e5007SSukumar Swaminathan oce_stat_init(struct oce_dev *dev)
1964d0e5007SSukumar Swaminathan {
1974d0e5007SSukumar Swaminathan 	struct oce_stat *stats;
1984d0e5007SSukumar Swaminathan 	uint32_t num_stats = sizeof (struct oce_stat) /
1994d0e5007SSukumar Swaminathan 	    sizeof (kstat_named_t);
2004d0e5007SSukumar Swaminathan 
2014d0e5007SSukumar Swaminathan 	/* allocate the kstat */
2024d0e5007SSukumar Swaminathan 	dev->oce_kstats = kstat_create(OCE_MOD_NAME, dev->dev_id, "stats",
2034d0e5007SSukumar Swaminathan 	    "net", KSTAT_TYPE_NAMED,
2044d0e5007SSukumar Swaminathan 	    num_stats, 0);
2054d0e5007SSukumar Swaminathan 	if (dev->oce_kstats == NULL) {
2064d0e5007SSukumar Swaminathan 		oce_log(dev, CE_NOTE, MOD_CONFIG,
2074d0e5007SSukumar Swaminathan 		    "kstat creation failed: 0x%p",
2084d0e5007SSukumar Swaminathan 		    (void *)dev->oce_kstats);
2094d0e5007SSukumar Swaminathan 		return (DDI_FAILURE);
2104d0e5007SSukumar Swaminathan 	}
2114d0e5007SSukumar Swaminathan 
2124d0e5007SSukumar Swaminathan 	/* allocate the device copy of the stats */
2134d0e5007SSukumar Swaminathan 	dev->stats_dbuf = oce_alloc_dma_buffer(dev,
2144d0e5007SSukumar Swaminathan 	    sizeof (struct mbx_get_nic_stats),
2155b9d3151SSukumar Swaminathan 	    NULL, DDI_DMA_CONSISTENT);
2164d0e5007SSukumar Swaminathan 	if (dev->stats_dbuf == NULL) {
2174d0e5007SSukumar Swaminathan 		oce_log(dev, CE_NOTE, MOD_CONFIG,
2184d0e5007SSukumar Swaminathan 		    "Could not allocate stats_dbuf: %p",
2194d0e5007SSukumar Swaminathan 		    (void *)dev->stats_dbuf);
2204d0e5007SSukumar Swaminathan 		kstat_delete(dev->oce_kstats);
2214d0e5007SSukumar Swaminathan 		return (DDI_FAILURE);
2224d0e5007SSukumar Swaminathan 	}
2234d0e5007SSukumar Swaminathan 	dev->hw_stats = (struct mbx_get_nic_stats *)DBUF_VA(dev->stats_dbuf);
2244d0e5007SSukumar Swaminathan 
2254d0e5007SSukumar Swaminathan 	/* initialize the counters */
2264d0e5007SSukumar Swaminathan 	stats = (struct oce_stat *)dev->oce_kstats->ks_data;
2274d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_bytes_hi, "rx bytes msd", KSTAT_DATA_ULONG);
2284d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_bytes_lo, "rx bytes lsd", KSTAT_DATA_ULONG);
2294d0e5007SSukumar Swaminathan 
2304d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_frames, "rx frames", KSTAT_DATA_ULONG);
2314d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_errors, "rx errors", KSTAT_DATA_ULONG);
2324d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_drops, "rx drops", KSTAT_DATA_ULONG);
2334d0e5007SSukumar Swaminathan 
2344d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_bytes_hi, "tx bytes msd", KSTAT_DATA_ULONG);
2354d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_bytes_lo, "tx bytes lsd", KSTAT_DATA_ULONG);
2364d0e5007SSukumar Swaminathan 
2374d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_frames, "tx frames", KSTAT_DATA_ULONG);
2384d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_errors, "tx errors", KSTAT_DATA_ULONG);
2394d0e5007SSukumar Swaminathan 
2404d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_unicast_frames,
2414d0e5007SSukumar Swaminathan 	    "rx unicast frames", KSTAT_DATA_ULONG);
2424d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_multicast_frames,
2434d0e5007SSukumar Swaminathan 	    "rx multicast frames", KSTAT_DATA_ULONG);
2444d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_broadcast_frames,
2454d0e5007SSukumar Swaminathan 	    "rx broadcast frames", KSTAT_DATA_ULONG);
2464d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_crc_errors,
2474d0e5007SSukumar Swaminathan 	    "rx crc errors", KSTAT_DATA_ULONG);
2484d0e5007SSukumar Swaminathan 
2494d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_alignment_symbol_errors,
2504d0e5007SSukumar Swaminathan 	    "rx alignment symbol errors", KSTAT_DATA_ULONG);
2514d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_in_range_errors,
2524d0e5007SSukumar Swaminathan 	    "rx in range errors", KSTAT_DATA_ULONG);
2534d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_out_range_errors,
2544d0e5007SSukumar Swaminathan 	    "rx out range errors", KSTAT_DATA_ULONG);
2554d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_frame_too_long,
2564d0e5007SSukumar Swaminathan 	    "rx frame too long", KSTAT_DATA_ULONG);
2574d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_address_match_errors,
2584d0e5007SSukumar Swaminathan 	    "rx address match errors", KSTAT_DATA_ULONG);
2594d0e5007SSukumar Swaminathan 
2604d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_pause_frames,
2614d0e5007SSukumar Swaminathan 	    "rx pause frames", KSTAT_DATA_ULONG);
2624d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_control_frames,
2634d0e5007SSukumar Swaminathan 	    "rx control frames", KSTAT_DATA_ULONG);
2644d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_ip_checksum_errs,
2654d0e5007SSukumar Swaminathan 	    "rx ip checksum errors", KSTAT_DATA_ULONG);
2664d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_tcp_checksum_errs,
2674d0e5007SSukumar Swaminathan 	    "rx tcp checksum errors", KSTAT_DATA_ULONG);
2684d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_udp_checksum_errs,
2694d0e5007SSukumar Swaminathan 	    "rx udp checksum errors", KSTAT_DATA_ULONG);
2704d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_fifo_overflow,
2714d0e5007SSukumar Swaminathan 	    "rx fifo overflow", KSTAT_DATA_ULONG);
2724d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->rx_input_fifo_overflow,
2734d0e5007SSukumar Swaminathan 	    "rx input fifo overflow", KSTAT_DATA_ULONG);
2744d0e5007SSukumar Swaminathan 
2754d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_unicast_frames,
2764d0e5007SSukumar Swaminathan 	    "tx unicast frames", KSTAT_DATA_ULONG);
2774d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_multicast_frames,
2784d0e5007SSukumar Swaminathan 	    "tx multicast frames", KSTAT_DATA_ULONG);
2794d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_broadcast_frames,
2804d0e5007SSukumar Swaminathan 	    "tx broadcast frames", KSTAT_DATA_ULONG);
2814d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_pause_frames,
2824d0e5007SSukumar Swaminathan 	    "tx pause frames", KSTAT_DATA_ULONG);
2834d0e5007SSukumar Swaminathan 	kstat_named_init(&stats->tx_control_frames,
2844d0e5007SSukumar Swaminathan 	    "tx control frames", KSTAT_DATA_ULONG);
2854d0e5007SSukumar Swaminathan 
286*3abb112fSGarrett D'Amore 
287*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_no_pbuf,
288*3abb112fSGarrett D'Amore 	    "rx_drops_no_pbuf", KSTAT_DATA_ULONG);
289*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_no_txpb,
290*3abb112fSGarrett D'Amore 	    "rx_drops_no_txpb", KSTAT_DATA_ULONG);
291*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_no_erx_descr,
292*3abb112fSGarrett D'Amore 	    "rx_drops_no_erx_descr", KSTAT_DATA_ULONG);
293*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_no_tpre_descr,
294*3abb112fSGarrett D'Amore 	    "rx_drops_no_tpre_descr", KSTAT_DATA_ULONG);
295*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_too_many_frags,
296*3abb112fSGarrett D'Amore 	    "rx_drops_too_many_frags", KSTAT_DATA_ULONG);
297*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_invalid_ring,
298*3abb112fSGarrett D'Amore 	    "rx_drops_invalid_ring", KSTAT_DATA_ULONG);
299*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_mtu,
300*3abb112fSGarrett D'Amore 	    "rx_drops_mtu", KSTAT_DATA_ULONG);
301*3abb112fSGarrett D'Amore 
302*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_dropped_too_small,
303*3abb112fSGarrett D'Amore 	    "rx_dropped_too_small", KSTAT_DATA_ULONG);
304*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_dropped_too_short,
305*3abb112fSGarrett D'Amore 	    "rx_dropped_too_short", KSTAT_DATA_ULONG);
306*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_dropped_header_too_small,
307*3abb112fSGarrett D'Amore 	    "rx_dropped_header_too_small", KSTAT_DATA_ULONG);
308*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_dropped_tcp_length,
309*3abb112fSGarrett D'Amore 	    "rx_dropped_tcp_length", KSTAT_DATA_ULONG);
310*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_dropped_runt,
311*3abb112fSGarrett D'Amore 	    "rx_dropped_runt", KSTAT_DATA_ULONG);
312*3abb112fSGarrett D'Amore 
313*3abb112fSGarrett D'Amore 	kstat_named_init(&stats->rx_drops_no_fragments,
314*3abb112fSGarrett D'Amore 	    "rx_drop_no_frag", KSTAT_DATA_ULONG);
315*3abb112fSGarrett D'Amore 
316*3abb112fSGarrett D'Amore 
3174d0e5007SSukumar Swaminathan 	dev->oce_kstats->ks_update = oce_update_stats;
3184d0e5007SSukumar Swaminathan 	dev->oce_kstats->ks_private = (void *)dev;
3194d0e5007SSukumar Swaminathan 	kstat_install(dev->oce_kstats);
3204d0e5007SSukumar Swaminathan 
3214d0e5007SSukumar Swaminathan 	return (DDI_SUCCESS);
3224d0e5007SSukumar Swaminathan } /* oce_stat_init */
3234d0e5007SSukumar Swaminathan 
3244d0e5007SSukumar Swaminathan /*
3254d0e5007SSukumar Swaminathan  * function to undo initialization done in oce_stat_init
3264d0e5007SSukumar Swaminathan  *
3274d0e5007SSukumar Swaminathan  * dev - software handle to the device
3284d0e5007SSukumar Swaminathan  *
3294d0e5007SSukumar Swaminathan  * return none
3304d0e5007SSukumar Swaminathan  */
3314d0e5007SSukumar Swaminathan void
oce_stat_fini(struct oce_dev * dev)3324d0e5007SSukumar Swaminathan oce_stat_fini(struct oce_dev *dev)
3334d0e5007SSukumar Swaminathan {
3344d0e5007SSukumar Swaminathan 	oce_free_dma_buffer(dev, dev->stats_dbuf);
3354d0e5007SSukumar Swaminathan 	dev->hw_stats = NULL;
3364d0e5007SSukumar Swaminathan 	dev->stats_dbuf = NULL;
3374d0e5007SSukumar Swaminathan 	kstat_delete(dev->oce_kstats);
3384d0e5007SSukumar Swaminathan 	dev->oce_kstats = NULL;
3394d0e5007SSukumar Swaminathan } /* oce_stat_fini */
3404d0e5007SSukumar Swaminathan 
3414d0e5007SSukumar Swaminathan /*
3424d0e5007SSukumar Swaminathan  * GLDv3 entry for statistic query
3434d0e5007SSukumar Swaminathan  */
3444d0e5007SSukumar Swaminathan int
oce_m_stat(void * arg,uint_t stat,uint64_t * val)3454d0e5007SSukumar Swaminathan oce_m_stat(void *arg, uint_t stat, uint64_t *val)
3464d0e5007SSukumar Swaminathan {
3474d0e5007SSukumar Swaminathan 	struct oce_dev *dev = arg;
3484d0e5007SSukumar Swaminathan 	struct oce_stat *stats;
3494d0e5007SSukumar Swaminathan 	struct rx_port_stats *port_stats;
3504d0e5007SSukumar Swaminathan 
3514d0e5007SSukumar Swaminathan 	stats = (struct oce_stat *)dev->oce_kstats->ks_data;
3524d0e5007SSukumar Swaminathan 	port_stats = &dev->hw_stats->params.rsp.rx.port[dev->port_id];
3534d0e5007SSukumar Swaminathan 
3544d0e5007SSukumar Swaminathan 	mutex_enter(&dev->dev_lock);
3554d0e5007SSukumar Swaminathan 
3564d0e5007SSukumar Swaminathan 	if (dev->suspended ||
3574d0e5007SSukumar Swaminathan 	    (dev->state & STATE_MAC_STOPPING) ||
3584d0e5007SSukumar Swaminathan 	    !(dev->state & STATE_MAC_STARTED)) {
3594d0e5007SSukumar Swaminathan 		mutex_exit(&dev->dev_lock);
3604d0e5007SSukumar Swaminathan 		return (EIO);
3614d0e5007SSukumar Swaminathan 	}
3624d0e5007SSukumar Swaminathan 
3634d0e5007SSukumar Swaminathan 	switch (stat) {
3645b9d3151SSukumar Swaminathan 	case MAC_STAT_IFSPEED: {
3655b9d3151SSukumar Swaminathan 		struct link_status link = {0};
3665b9d3151SSukumar Swaminathan 		if (dev->link_speed < 0) {
3675b9d3151SSukumar Swaminathan 			(void) oce_get_link_status(dev, &link);
3685b9d3151SSukumar Swaminathan 			dev->link_speed = link.qos_link_speed ?
3695b9d3151SSukumar Swaminathan 			    link.qos_link_speed * 10 :
3705b9d3151SSukumar Swaminathan 			    pow10[link.mac_speed];
3715b9d3151SSukumar Swaminathan 		}
3725b9d3151SSukumar Swaminathan 		*val = dev->link_speed * 1000000ull;
3735b9d3151SSukumar Swaminathan 	}
3744d0e5007SSukumar Swaminathan 	break;
3754d0e5007SSukumar Swaminathan 
3764d0e5007SSukumar Swaminathan 	case MAC_STAT_RBYTES:
3774d0e5007SSukumar Swaminathan 		stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd;
3784d0e5007SSukumar Swaminathan 		stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd;
3794d0e5007SSukumar Swaminathan 		*val = (uint64_t)stats->rx_bytes_hi.value.ul << 32 |
3804d0e5007SSukumar Swaminathan 		    (uint64_t)stats->rx_bytes_lo.value.ul;
3814d0e5007SSukumar Swaminathan 	break;
3824d0e5007SSukumar Swaminathan 
3834d0e5007SSukumar Swaminathan 	case MAC_STAT_IPACKETS:
3844d0e5007SSukumar Swaminathan 		stats->rx_frames.value.ul = port_stats->rx_total_frames;
3854d0e5007SSukumar Swaminathan 		*val = stats->rx_frames.value.ul;
3864d0e5007SSukumar Swaminathan 	break;
3874d0e5007SSukumar Swaminathan 
3884d0e5007SSukumar Swaminathan 	case MAC_STAT_OBYTES:
3894d0e5007SSukumar Swaminathan 		stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd;
3904d0e5007SSukumar Swaminathan 		stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd;
3914d0e5007SSukumar Swaminathan 		*val = (uint64_t)stats->tx_bytes_hi.value.ul << 32 |
3924d0e5007SSukumar Swaminathan 		    (uint64_t)stats->tx_bytes_lo.value.ul;
3934d0e5007SSukumar Swaminathan 	break;
3944d0e5007SSukumar Swaminathan 
3954d0e5007SSukumar Swaminathan 	case MAC_STAT_OPACKETS:
3964d0e5007SSukumar Swaminathan 		stats->tx_frames.value.ul = port_stats->tx_unicast_frames +
3974d0e5007SSukumar Swaminathan 		    port_stats->tx_multicast_frames +
3984d0e5007SSukumar Swaminathan 		    port_stats->tx_broadcast_frames +
3994d0e5007SSukumar Swaminathan 		    port_stats->tx_pause_frames +
4004d0e5007SSukumar Swaminathan 		    port_stats->tx_control_frames;
4014d0e5007SSukumar Swaminathan 		*val = stats->tx_frames.value.ul;
4024d0e5007SSukumar Swaminathan 	break;
4034d0e5007SSukumar Swaminathan 
4044d0e5007SSukumar Swaminathan 	case MAC_STAT_BRDCSTRCV:
4054d0e5007SSukumar Swaminathan 		stats->rx_broadcast_frames.value.ul =
4064d0e5007SSukumar Swaminathan 		    port_stats->rx_broadcast_frames;
4074d0e5007SSukumar Swaminathan 		*val = stats->rx_broadcast_frames.value.ul;
4084d0e5007SSukumar Swaminathan 	break;
4094d0e5007SSukumar Swaminathan 
4104d0e5007SSukumar Swaminathan 	case MAC_STAT_MULTIRCV:
4114d0e5007SSukumar Swaminathan 		stats->rx_multicast_frames.value.ul =
4124d0e5007SSukumar Swaminathan 		    port_stats->rx_multicast_frames;
4134d0e5007SSukumar Swaminathan 		*val = stats->rx_multicast_frames.value.ul;
4144d0e5007SSukumar Swaminathan 	break;
4154d0e5007SSukumar Swaminathan 
4164d0e5007SSukumar Swaminathan 	case MAC_STAT_MULTIXMT:
4174d0e5007SSukumar Swaminathan 		stats->tx_multicast_frames.value.ul =
4184d0e5007SSukumar Swaminathan 		    port_stats->tx_multicast_frames;
4194d0e5007SSukumar Swaminathan 		*val = stats->tx_multicast_frames.value.ul;
4204d0e5007SSukumar Swaminathan 	break;
4214d0e5007SSukumar Swaminathan 
4224d0e5007SSukumar Swaminathan 	case MAC_STAT_BRDCSTXMT:
4234d0e5007SSukumar Swaminathan 		stats->tx_broadcast_frames.value.ul =
4244d0e5007SSukumar Swaminathan 		    port_stats->tx_broadcast_frames;
4254d0e5007SSukumar Swaminathan 		*val = stats->tx_broadcast_frames.value.ul;
4264d0e5007SSukumar Swaminathan 	break;
4274d0e5007SSukumar Swaminathan 
4284d0e5007SSukumar Swaminathan 	case MAC_STAT_NORCVBUF:
4294d0e5007SSukumar Swaminathan 		stats->rx_fifo_overflow.value.ul =
4304d0e5007SSukumar Swaminathan 		    port_stats->rx_fifo_overflow;
4314d0e5007SSukumar Swaminathan 		*val = stats->rx_fifo_overflow.value.ul;
4324d0e5007SSukumar Swaminathan 	break;
4334d0e5007SSukumar Swaminathan 
4344d0e5007SSukumar Swaminathan 	case MAC_STAT_IERRORS:
4354d0e5007SSukumar Swaminathan 		stats->rx_errors.value.ul = port_stats->rx_crc_errors +
4364d0e5007SSukumar Swaminathan 		    port_stats->rx_alignment_symbol_errors +
4374d0e5007SSukumar Swaminathan 		    port_stats->rx_in_range_errors +
4384d0e5007SSukumar Swaminathan 		    port_stats->rx_out_range_errors +
4394d0e5007SSukumar Swaminathan 		    port_stats->rx_frame_too_long +
4404d0e5007SSukumar Swaminathan 		    port_stats->rx_ip_checksum_errs +
4414d0e5007SSukumar Swaminathan 		    port_stats->rx_tcp_checksum_errs +
4424d0e5007SSukumar Swaminathan 		    port_stats->rx_udp_checksum_errs;
4434d0e5007SSukumar Swaminathan 		*val = stats->rx_errors.value.ul;
4444d0e5007SSukumar Swaminathan 	break;
4454d0e5007SSukumar Swaminathan 
4464d0e5007SSukumar Swaminathan 	case MAC_STAT_NOXMTBUF:
4474d0e5007SSukumar Swaminathan 		*val = dev->tx_noxmtbuf;
4484d0e5007SSukumar Swaminathan 	break;
4494d0e5007SSukumar Swaminathan 
4504d0e5007SSukumar Swaminathan 	case MAC_STAT_OERRORS:
4514d0e5007SSukumar Swaminathan 		*val = stats->tx_errors.value.ul;
4524d0e5007SSukumar Swaminathan 	break;
4534d0e5007SSukumar Swaminathan 
4544d0e5007SSukumar Swaminathan 	case ETHER_STAT_LINK_DUPLEX:
4554d0e5007SSukumar Swaminathan 		if (dev->state & STATE_MAC_STARTED)
4564d0e5007SSukumar Swaminathan 			*val = LINK_DUPLEX_FULL;
4574d0e5007SSukumar Swaminathan 		else
4584d0e5007SSukumar Swaminathan 			*val = LINK_DUPLEX_UNKNOWN;
4594d0e5007SSukumar Swaminathan 	break;
4604d0e5007SSukumar Swaminathan 
4614d0e5007SSukumar Swaminathan 	case ETHER_STAT_ALIGN_ERRORS:
4624d0e5007SSukumar Swaminathan 		stats->rx_alignment_symbol_errors.value.ul =
4634d0e5007SSukumar Swaminathan 		    port_stats->rx_alignment_symbol_errors;
4644d0e5007SSukumar Swaminathan 		*val = port_stats->rx_alignment_symbol_errors;
4654d0e5007SSukumar Swaminathan 	break;
4664d0e5007SSukumar Swaminathan 
4674d0e5007SSukumar Swaminathan 	case ETHER_STAT_FCS_ERRORS:
4684d0e5007SSukumar Swaminathan 		stats->rx_crc_errors.value.ul =
4694d0e5007SSukumar Swaminathan 		    port_stats->rx_crc_errors;
4704d0e5007SSukumar Swaminathan 		*val = port_stats->rx_crc_errors;
4714d0e5007SSukumar Swaminathan 	break;
4724d0e5007SSukumar Swaminathan 
4734d0e5007SSukumar Swaminathan 	case ETHER_STAT_MACRCV_ERRORS:
4744d0e5007SSukumar Swaminathan 		stats->rx_errors.value.ul = port_stats->rx_crc_errors +
4754d0e5007SSukumar Swaminathan 		    port_stats->rx_alignment_symbol_errors +
4764d0e5007SSukumar Swaminathan 		    port_stats->rx_in_range_errors +
4774d0e5007SSukumar Swaminathan 		    port_stats->rx_out_range_errors +
4784d0e5007SSukumar Swaminathan 		    port_stats->rx_frame_too_long +
4794d0e5007SSukumar Swaminathan 		    port_stats->rx_ip_checksum_errs +
4804d0e5007SSukumar Swaminathan 		    port_stats->rx_tcp_checksum_errs +
4814d0e5007SSukumar Swaminathan 		    port_stats->rx_udp_checksum_errs;
4824d0e5007SSukumar Swaminathan 
4834d0e5007SSukumar Swaminathan 		*val = stats->rx_errors.value.ul;
4844d0e5007SSukumar Swaminathan 	break;
4854d0e5007SSukumar Swaminathan 
4864d0e5007SSukumar Swaminathan 	case ETHER_STAT_MACXMT_ERRORS:
4874d0e5007SSukumar Swaminathan 		*val = stats->tx_errors.value.ul;
4884d0e5007SSukumar Swaminathan 	break;
4894d0e5007SSukumar Swaminathan 
4904d0e5007SSukumar Swaminathan 	case ETHER_STAT_TOOLONG_ERRORS:
4914d0e5007SSukumar Swaminathan 		stats->rx_frame_too_long.value.ul =
4924d0e5007SSukumar Swaminathan 		    port_stats->rx_frame_too_long;
4934d0e5007SSukumar Swaminathan 		*val = port_stats->rx_frame_too_long;
4944d0e5007SSukumar Swaminathan 	break;
4954d0e5007SSukumar Swaminathan 
4964d0e5007SSukumar Swaminathan 	case ETHER_STAT_CAP_PAUSE:
4974d0e5007SSukumar Swaminathan 	case ETHER_STAT_LINK_PAUSE:
4984d0e5007SSukumar Swaminathan 		if (dev->flow_control & OCE_FC_TX &&
4994d0e5007SSukumar Swaminathan 		    dev->flow_control & OCE_FC_RX)
5004d0e5007SSukumar Swaminathan 			*val = LINK_FLOWCTRL_BI;
5014d0e5007SSukumar Swaminathan 		else if (dev->flow_control == OCE_FC_TX)
5024d0e5007SSukumar Swaminathan 			*val = LINK_FLOWCTRL_TX;
5034d0e5007SSukumar Swaminathan 		else if (dev->flow_control == OCE_FC_RX)
5044d0e5007SSukumar Swaminathan 			*val = LINK_FLOWCTRL_RX;
5054d0e5007SSukumar Swaminathan 		else if (dev->flow_control == 0)
5064d0e5007SSukumar Swaminathan 			*val = LINK_FLOWCTRL_NONE;
5074d0e5007SSukumar Swaminathan 	break;
5084d0e5007SSukumar Swaminathan 
5094d0e5007SSukumar Swaminathan 	default:
5108d738d7dSSukumar Swaminathan 		mutex_exit(&dev->dev_lock);
5114d0e5007SSukumar Swaminathan 		return (ENOTSUP);
5124d0e5007SSukumar Swaminathan 	}
5138d738d7dSSukumar Swaminathan 	mutex_exit(&dev->dev_lock);
5144d0e5007SSukumar Swaminathan 	return (0);
5154d0e5007SSukumar Swaminathan } /* oce_m_stat */
516