17d6f728cSVishwanathapura, Niranjana /*
27d6f728cSVishwanathapura, Niranjana  * Copyright(c) 2017 Intel Corporation.
37d6f728cSVishwanathapura, Niranjana  *
47d6f728cSVishwanathapura, Niranjana  * This file is provided under a dual BSD/GPLv2 license.  When using or
57d6f728cSVishwanathapura, Niranjana  * redistributing this file, you may do so under either license.
67d6f728cSVishwanathapura, Niranjana  *
77d6f728cSVishwanathapura, Niranjana  * GPL LICENSE SUMMARY
87d6f728cSVishwanathapura, Niranjana  *
97d6f728cSVishwanathapura, Niranjana  * This program is free software; you can redistribute it and/or modify
107d6f728cSVishwanathapura, Niranjana  * it under the terms of version 2 of the GNU General Public License as
117d6f728cSVishwanathapura, Niranjana  * published by the Free Software Foundation.
127d6f728cSVishwanathapura, Niranjana  *
137d6f728cSVishwanathapura, Niranjana  * This program is distributed in the hope that it will be useful, but
147d6f728cSVishwanathapura, Niranjana  * WITHOUT ANY WARRANTY; without even the implied warranty of
157d6f728cSVishwanathapura, Niranjana  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
167d6f728cSVishwanathapura, Niranjana  * General Public License for more details.
177d6f728cSVishwanathapura, Niranjana  *
187d6f728cSVishwanathapura, Niranjana  * BSD LICENSE
197d6f728cSVishwanathapura, Niranjana  *
207d6f728cSVishwanathapura, Niranjana  * Redistribution and use in source and binary forms, with or without
217d6f728cSVishwanathapura, Niranjana  * modification, are permitted provided that the following conditions
227d6f728cSVishwanathapura, Niranjana  * are met:
237d6f728cSVishwanathapura, Niranjana  *
247d6f728cSVishwanathapura, Niranjana  *  - Redistributions of source code must retain the above copyright
257d6f728cSVishwanathapura, Niranjana  *    notice, this list of conditions and the following disclaimer.
267d6f728cSVishwanathapura, Niranjana  *  - Redistributions in binary form must reproduce the above copyright
277d6f728cSVishwanathapura, Niranjana  *    notice, this list of conditions and the following disclaimer in
287d6f728cSVishwanathapura, Niranjana  *    the documentation and/or other materials provided with the
297d6f728cSVishwanathapura, Niranjana  *    distribution.
307d6f728cSVishwanathapura, Niranjana  *  - Neither the name of Intel Corporation nor the names of its
317d6f728cSVishwanathapura, Niranjana  *    contributors may be used to endorse or promote products derived
327d6f728cSVishwanathapura, Niranjana  *    from this software without specific prior written permission.
337d6f728cSVishwanathapura, Niranjana  *
347d6f728cSVishwanathapura, Niranjana  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
357d6f728cSVishwanathapura, Niranjana  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
367d6f728cSVishwanathapura, Niranjana  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
377d6f728cSVishwanathapura, Niranjana  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
387d6f728cSVishwanathapura, Niranjana  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
397d6f728cSVishwanathapura, Niranjana  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
407d6f728cSVishwanathapura, Niranjana  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
417d6f728cSVishwanathapura, Niranjana  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
427d6f728cSVishwanathapura, Niranjana  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
437d6f728cSVishwanathapura, Niranjana  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
447d6f728cSVishwanathapura, Niranjana  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
457d6f728cSVishwanathapura, Niranjana  *
467d6f728cSVishwanathapura, Niranjana  */
477d6f728cSVishwanathapura, Niranjana 
487d6f728cSVishwanathapura, Niranjana /*
497d6f728cSVishwanathapura, Niranjana  * This file contains OPA VNIC ethtool functions
507d6f728cSVishwanathapura, Niranjana  */
517d6f728cSVishwanathapura, Niranjana 
527d6f728cSVishwanathapura, Niranjana #include <linux/ethtool.h>
537d6f728cSVishwanathapura, Niranjana 
547d6f728cSVishwanathapura, Niranjana #include "opa_vnic_internal.h"
557d6f728cSVishwanathapura, Niranjana 
56009b7dd4SVishwanathapura, Niranjana enum {NETDEV_STATS, VNIC_STATS};
57009b7dd4SVishwanathapura, Niranjana 
58009b7dd4SVishwanathapura, Niranjana struct vnic_stats {
59009b7dd4SVishwanathapura, Niranjana 	char stat_string[ETH_GSTRING_LEN];
60009b7dd4SVishwanathapura, Niranjana 	struct {
61009b7dd4SVishwanathapura, Niranjana 		int sizeof_stat;
62009b7dd4SVishwanathapura, Niranjana 		int stat_offset;
63009b7dd4SVishwanathapura, Niranjana 	};
64009b7dd4SVishwanathapura, Niranjana };
65009b7dd4SVishwanathapura, Niranjana 
66c593642cSPankaj Bharadiya #define VNIC_STAT(m)            { sizeof_field(struct opa_vnic_stats, m),   \
67009b7dd4SVishwanathapura, Niranjana 				  offsetof(struct opa_vnic_stats, m) }
68009b7dd4SVishwanathapura, Niranjana 
69009b7dd4SVishwanathapura, Niranjana static struct vnic_stats vnic_gstrings_stats[] = {
70009b7dd4SVishwanathapura, Niranjana 	/* NETDEV stats */
71009b7dd4SVishwanathapura, Niranjana 	{"rx_packets", VNIC_STAT(netstats.rx_packets)},
72009b7dd4SVishwanathapura, Niranjana 	{"tx_packets", VNIC_STAT(netstats.tx_packets)},
73009b7dd4SVishwanathapura, Niranjana 	{"rx_bytes", VNIC_STAT(netstats.rx_bytes)},
74009b7dd4SVishwanathapura, Niranjana 	{"tx_bytes", VNIC_STAT(netstats.tx_bytes)},
75009b7dd4SVishwanathapura, Niranjana 	{"rx_errors", VNIC_STAT(netstats.rx_errors)},
76009b7dd4SVishwanathapura, Niranjana 	{"tx_errors", VNIC_STAT(netstats.tx_errors)},
77009b7dd4SVishwanathapura, Niranjana 	{"rx_dropped", VNIC_STAT(netstats.rx_dropped)},
78009b7dd4SVishwanathapura, Niranjana 	{"tx_dropped", VNIC_STAT(netstats.tx_dropped)},
79009b7dd4SVishwanathapura, Niranjana 
80009b7dd4SVishwanathapura, Niranjana 	/* SUMMARY counters */
81009b7dd4SVishwanathapura, Niranjana 	{"tx_unicast", VNIC_STAT(tx_grp.unicast)},
82009b7dd4SVishwanathapura, Niranjana 	{"tx_mcastbcast", VNIC_STAT(tx_grp.mcastbcast)},
83009b7dd4SVishwanathapura, Niranjana 	{"tx_untagged", VNIC_STAT(tx_grp.untagged)},
84009b7dd4SVishwanathapura, Niranjana 	{"tx_vlan", VNIC_STAT(tx_grp.vlan)},
85009b7dd4SVishwanathapura, Niranjana 
86009b7dd4SVishwanathapura, Niranjana 	{"tx_64_size", VNIC_STAT(tx_grp.s_64)},
87009b7dd4SVishwanathapura, Niranjana 	{"tx_65_127", VNIC_STAT(tx_grp.s_65_127)},
88009b7dd4SVishwanathapura, Niranjana 	{"tx_128_255", VNIC_STAT(tx_grp.s_128_255)},
89009b7dd4SVishwanathapura, Niranjana 	{"tx_256_511", VNIC_STAT(tx_grp.s_256_511)},
90009b7dd4SVishwanathapura, Niranjana 	{"tx_512_1023", VNIC_STAT(tx_grp.s_512_1023)},
91009b7dd4SVishwanathapura, Niranjana 	{"tx_1024_1518", VNIC_STAT(tx_grp.s_1024_1518)},
92009b7dd4SVishwanathapura, Niranjana 	{"tx_1519_max", VNIC_STAT(tx_grp.s_1519_max)},
93009b7dd4SVishwanathapura, Niranjana 
94009b7dd4SVishwanathapura, Niranjana 	{"rx_unicast", VNIC_STAT(rx_grp.unicast)},
95009b7dd4SVishwanathapura, Niranjana 	{"rx_mcastbcast", VNIC_STAT(rx_grp.mcastbcast)},
96009b7dd4SVishwanathapura, Niranjana 	{"rx_untagged", VNIC_STAT(rx_grp.untagged)},
97009b7dd4SVishwanathapura, Niranjana 	{"rx_vlan", VNIC_STAT(rx_grp.vlan)},
98009b7dd4SVishwanathapura, Niranjana 
99009b7dd4SVishwanathapura, Niranjana 	{"rx_64_size", VNIC_STAT(rx_grp.s_64)},
100009b7dd4SVishwanathapura, Niranjana 	{"rx_65_127", VNIC_STAT(rx_grp.s_65_127)},
101009b7dd4SVishwanathapura, Niranjana 	{"rx_128_255", VNIC_STAT(rx_grp.s_128_255)},
102009b7dd4SVishwanathapura, Niranjana 	{"rx_256_511", VNIC_STAT(rx_grp.s_256_511)},
103009b7dd4SVishwanathapura, Niranjana 	{"rx_512_1023", VNIC_STAT(rx_grp.s_512_1023)},
104009b7dd4SVishwanathapura, Niranjana 	{"rx_1024_1518", VNIC_STAT(rx_grp.s_1024_1518)},
105009b7dd4SVishwanathapura, Niranjana 	{"rx_1519_max", VNIC_STAT(rx_grp.s_1519_max)},
106009b7dd4SVishwanathapura, Niranjana 
107009b7dd4SVishwanathapura, Niranjana 	/* ERROR counters */
108009b7dd4SVishwanathapura, Niranjana 	{"rx_fifo_errors", VNIC_STAT(netstats.rx_fifo_errors)},
109009b7dd4SVishwanathapura, Niranjana 	{"rx_length_errors", VNIC_STAT(netstats.rx_length_errors)},
110009b7dd4SVishwanathapura, Niranjana 
111009b7dd4SVishwanathapura, Niranjana 	{"tx_fifo_errors", VNIC_STAT(netstats.tx_fifo_errors)},
112009b7dd4SVishwanathapura, Niranjana 	{"tx_carrier_errors", VNIC_STAT(netstats.tx_carrier_errors)},
113009b7dd4SVishwanathapura, Niranjana 
114009b7dd4SVishwanathapura, Niranjana 	{"tx_dlid_zero", VNIC_STAT(tx_dlid_zero)},
115009b7dd4SVishwanathapura, Niranjana 	{"tx_drop_state", VNIC_STAT(tx_drop_state)},
116009b7dd4SVishwanathapura, Niranjana 	{"rx_drop_state", VNIC_STAT(rx_drop_state)},
117009b7dd4SVishwanathapura, Niranjana 	{"rx_oversize", VNIC_STAT(rx_oversize)},
118009b7dd4SVishwanathapura, Niranjana 	{"rx_runt", VNIC_STAT(rx_runt)},
119009b7dd4SVishwanathapura, Niranjana };
120009b7dd4SVishwanathapura, Niranjana 
121009b7dd4SVishwanathapura, Niranjana #define VNIC_STATS_LEN  ARRAY_SIZE(vnic_gstrings_stats)
122009b7dd4SVishwanathapura, Niranjana 
1231bd671abSVishwanathapura, Niranjana /* vnic_get_drvinfo - get driver info */
vnic_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)1241bd671abSVishwanathapura, Niranjana static void vnic_get_drvinfo(struct net_device *netdev,
1251bd671abSVishwanathapura, Niranjana 			     struct ethtool_drvinfo *drvinfo)
1261bd671abSVishwanathapura, Niranjana {
127*2c34bb6dSWolfram Sang 	strscpy(drvinfo->driver, opa_vnic_driver_name, sizeof(drvinfo->driver));
128*2c34bb6dSWolfram Sang 	strscpy(drvinfo->bus_info, dev_name(netdev->dev.parent),
1291bd671abSVishwanathapura, Niranjana 		sizeof(drvinfo->bus_info));
1301bd671abSVishwanathapura, Niranjana }
1311bd671abSVishwanathapura, Niranjana 
132009b7dd4SVishwanathapura, Niranjana /* vnic_get_sset_count - get string set count */
vnic_get_sset_count(struct net_device * netdev,int sset)133009b7dd4SVishwanathapura, Niranjana static int vnic_get_sset_count(struct net_device *netdev, int sset)
134009b7dd4SVishwanathapura, Niranjana {
135009b7dd4SVishwanathapura, Niranjana 	return (sset == ETH_SS_STATS) ? VNIC_STATS_LEN : -EOPNOTSUPP;
136009b7dd4SVishwanathapura, Niranjana }
137009b7dd4SVishwanathapura, Niranjana 
138009b7dd4SVishwanathapura, Niranjana /* vnic_get_ethtool_stats - get statistics */
vnic_get_ethtool_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)139009b7dd4SVishwanathapura, Niranjana static void vnic_get_ethtool_stats(struct net_device *netdev,
140009b7dd4SVishwanathapura, Niranjana 				   struct ethtool_stats *stats, u64 *data)
141009b7dd4SVishwanathapura, Niranjana {
142009b7dd4SVishwanathapura, Niranjana 	struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev);
143009b7dd4SVishwanathapura, Niranjana 	struct opa_vnic_stats vstats;
144009b7dd4SVishwanathapura, Niranjana 	int i;
145009b7dd4SVishwanathapura, Niranjana 
146009b7dd4SVishwanathapura, Niranjana 	memset(&vstats, 0, sizeof(vstats));
147a379d69fSVishwanathapura, Niranjana 	spin_lock(&adapter->stats_lock);
148009b7dd4SVishwanathapura, Niranjana 	adapter->rn_ops->ndo_get_stats64(netdev, &vstats.netstats);
149a379d69fSVishwanathapura, Niranjana 	spin_unlock(&adapter->stats_lock);
150009b7dd4SVishwanathapura, Niranjana 	for (i = 0; i < VNIC_STATS_LEN; i++) {
151009b7dd4SVishwanathapura, Niranjana 		char *p = (char *)&vstats + vnic_gstrings_stats[i].stat_offset;
152009b7dd4SVishwanathapura, Niranjana 
153009b7dd4SVishwanathapura, Niranjana 		data[i] = (vnic_gstrings_stats[i].sizeof_stat ==
154009b7dd4SVishwanathapura, Niranjana 			   sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
155009b7dd4SVishwanathapura, Niranjana 	}
156009b7dd4SVishwanathapura, Niranjana }
157009b7dd4SVishwanathapura, Niranjana 
158009b7dd4SVishwanathapura, Niranjana /* vnic_get_strings - get strings */
vnic_get_strings(struct net_device * netdev,u32 stringset,u8 * data)159009b7dd4SVishwanathapura, Niranjana static void vnic_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
160009b7dd4SVishwanathapura, Niranjana {
161009b7dd4SVishwanathapura, Niranjana 	int i;
162009b7dd4SVishwanathapura, Niranjana 
163009b7dd4SVishwanathapura, Niranjana 	if (stringset != ETH_SS_STATS)
164009b7dd4SVishwanathapura, Niranjana 		return;
165009b7dd4SVishwanathapura, Niranjana 
166009b7dd4SVishwanathapura, Niranjana 	for (i = 0; i < VNIC_STATS_LEN; i++)
167009b7dd4SVishwanathapura, Niranjana 		memcpy(data + i * ETH_GSTRING_LEN,
168009b7dd4SVishwanathapura, Niranjana 		       vnic_gstrings_stats[i].stat_string,
169009b7dd4SVishwanathapura, Niranjana 		       ETH_GSTRING_LEN);
170009b7dd4SVishwanathapura, Niranjana }
171009b7dd4SVishwanathapura, Niranjana 
1727d6f728cSVishwanathapura, Niranjana /* ethtool ops */
1737d6f728cSVishwanathapura, Niranjana static const struct ethtool_ops opa_vnic_ethtool_ops = {
1741bd671abSVishwanathapura, Niranjana 	.get_drvinfo = vnic_get_drvinfo,
1757d6f728cSVishwanathapura, Niranjana 	.get_link = ethtool_op_get_link,
176009b7dd4SVishwanathapura, Niranjana 	.get_strings = vnic_get_strings,
177009b7dd4SVishwanathapura, Niranjana 	.get_sset_count = vnic_get_sset_count,
178009b7dd4SVishwanathapura, Niranjana 	.get_ethtool_stats = vnic_get_ethtool_stats,
1797d6f728cSVishwanathapura, Niranjana };
1807d6f728cSVishwanathapura, Niranjana 
1817d6f728cSVishwanathapura, Niranjana /* opa_vnic_set_ethtool_ops - set ethtool ops */
opa_vnic_set_ethtool_ops(struct net_device * netdev)1827d6f728cSVishwanathapura, Niranjana void opa_vnic_set_ethtool_ops(struct net_device *netdev)
1837d6f728cSVishwanathapura, Niranjana {
1847d6f728cSVishwanathapura, Niranjana 	netdev->ethtool_ops = &opa_vnic_ethtool_ops;
1857d6f728cSVishwanathapura, Niranjana }
186