Commit | Line | Data |
---|---|---|
7d6f728c VN |
1 | /* |
2 | * Copyright(c) 2017 Intel Corporation. | |
3 | * | |
4 | * This file is provided under a dual BSD/GPLv2 license. When using or | |
5 | * redistributing this file, you may do so under either license. | |
6 | * | |
7 | * GPL LICENSE SUMMARY | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of version 2 of the GNU General Public License as | |
11 | * published by the Free Software Foundation. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * BSD LICENSE | |
19 | * | |
20 | * Redistribution and use in source and binary forms, with or without | |
21 | * modification, are permitted provided that the following conditions | |
22 | * are met: | |
23 | * | |
24 | * - Redistributions of source code must retain the above copyright | |
25 | * notice, this list of conditions and the following disclaimer. | |
26 | * - Redistributions in binary form must reproduce the above copyright | |
27 | * notice, this list of conditions and the following disclaimer in | |
28 | * the documentation and/or other materials provided with the | |
29 | * distribution. | |
30 | * - Neither the name of Intel Corporation nor the names of its | |
31 | * contributors may be used to endorse or promote products derived | |
32 | * from this software without specific prior written permission. | |
33 | * | |
34 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
35 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
36 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
37 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
38 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
39 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
40 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
41 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
42 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
43 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
44 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
45 | * | |
46 | */ | |
47 | ||
48 | /* | |
49 | * This file contains OPA VNIC ethtool functions | |
50 | */ | |
51 | ||
52 | #include <linux/ethtool.h> | |
53 | ||
54 | #include "opa_vnic_internal.h" | |
55 | ||
009b7dd4 VN |
56 | enum {NETDEV_STATS, VNIC_STATS}; |
57 | ||
58 | struct vnic_stats { | |
59 | char stat_string[ETH_GSTRING_LEN]; | |
60 | struct { | |
61 | int sizeof_stat; | |
62 | int stat_offset; | |
63 | }; | |
64 | }; | |
65 | ||
c593642c | 66 | #define VNIC_STAT(m) { sizeof_field(struct opa_vnic_stats, m), \ |
009b7dd4 VN |
67 | offsetof(struct opa_vnic_stats, m) } |
68 | ||
69 | static struct vnic_stats vnic_gstrings_stats[] = { | |
70 | /* NETDEV stats */ | |
71 | {"rx_packets", VNIC_STAT(netstats.rx_packets)}, | |
72 | {"tx_packets", VNIC_STAT(netstats.tx_packets)}, | |
73 | {"rx_bytes", VNIC_STAT(netstats.rx_bytes)}, | |
74 | {"tx_bytes", VNIC_STAT(netstats.tx_bytes)}, | |
75 | {"rx_errors", VNIC_STAT(netstats.rx_errors)}, | |
76 | {"tx_errors", VNIC_STAT(netstats.tx_errors)}, | |
77 | {"rx_dropped", VNIC_STAT(netstats.rx_dropped)}, | |
78 | {"tx_dropped", VNIC_STAT(netstats.tx_dropped)}, | |
79 | ||
80 | /* SUMMARY counters */ | |
81 | {"tx_unicast", VNIC_STAT(tx_grp.unicast)}, | |
82 | {"tx_mcastbcast", VNIC_STAT(tx_grp.mcastbcast)}, | |
83 | {"tx_untagged", VNIC_STAT(tx_grp.untagged)}, | |
84 | {"tx_vlan", VNIC_STAT(tx_grp.vlan)}, | |
85 | ||
86 | {"tx_64_size", VNIC_STAT(tx_grp.s_64)}, | |
87 | {"tx_65_127", VNIC_STAT(tx_grp.s_65_127)}, | |
88 | {"tx_128_255", VNIC_STAT(tx_grp.s_128_255)}, | |
89 | {"tx_256_511", VNIC_STAT(tx_grp.s_256_511)}, | |
90 | {"tx_512_1023", VNIC_STAT(tx_grp.s_512_1023)}, | |
91 | {"tx_1024_1518", VNIC_STAT(tx_grp.s_1024_1518)}, | |
92 | {"tx_1519_max", VNIC_STAT(tx_grp.s_1519_max)}, | |
93 | ||
94 | {"rx_unicast", VNIC_STAT(rx_grp.unicast)}, | |
95 | {"rx_mcastbcast", VNIC_STAT(rx_grp.mcastbcast)}, | |
96 | {"rx_untagged", VNIC_STAT(rx_grp.untagged)}, | |
97 | {"rx_vlan", VNIC_STAT(rx_grp.vlan)}, | |
98 | ||
99 | {"rx_64_size", VNIC_STAT(rx_grp.s_64)}, | |
100 | {"rx_65_127", VNIC_STAT(rx_grp.s_65_127)}, | |
101 | {"rx_128_255", VNIC_STAT(rx_grp.s_128_255)}, | |
102 | {"rx_256_511", VNIC_STAT(rx_grp.s_256_511)}, | |
103 | {"rx_512_1023", VNIC_STAT(rx_grp.s_512_1023)}, | |
104 | {"rx_1024_1518", VNIC_STAT(rx_grp.s_1024_1518)}, | |
105 | {"rx_1519_max", VNIC_STAT(rx_grp.s_1519_max)}, | |
106 | ||
107 | /* ERROR counters */ | |
108 | {"rx_fifo_errors", VNIC_STAT(netstats.rx_fifo_errors)}, | |
109 | {"rx_length_errors", VNIC_STAT(netstats.rx_length_errors)}, | |
110 | ||
111 | {"tx_fifo_errors", VNIC_STAT(netstats.tx_fifo_errors)}, | |
112 | {"tx_carrier_errors", VNIC_STAT(netstats.tx_carrier_errors)}, | |
113 | ||
114 | {"tx_dlid_zero", VNIC_STAT(tx_dlid_zero)}, | |
115 | {"tx_drop_state", VNIC_STAT(tx_drop_state)}, | |
116 | {"rx_drop_state", VNIC_STAT(rx_drop_state)}, | |
117 | {"rx_oversize", VNIC_STAT(rx_oversize)}, | |
118 | {"rx_runt", VNIC_STAT(rx_runt)}, | |
119 | }; | |
120 | ||
121 | #define VNIC_STATS_LEN ARRAY_SIZE(vnic_gstrings_stats) | |
122 | ||
1bd671ab VN |
123 | /* vnic_get_drvinfo - get driver info */ |
124 | static void vnic_get_drvinfo(struct net_device *netdev, | |
125 | struct ethtool_drvinfo *drvinfo) | |
126 | { | |
127 | strlcpy(drvinfo->driver, opa_vnic_driver_name, sizeof(drvinfo->driver)); | |
128 | strlcpy(drvinfo->version, opa_vnic_driver_version, | |
129 | sizeof(drvinfo->version)); | |
130 | strlcpy(drvinfo->bus_info, dev_name(netdev->dev.parent), | |
131 | sizeof(drvinfo->bus_info)); | |
132 | } | |
133 | ||
009b7dd4 VN |
134 | /* vnic_get_sset_count - get string set count */ |
135 | static int vnic_get_sset_count(struct net_device *netdev, int sset) | |
136 | { | |
137 | return (sset == ETH_SS_STATS) ? VNIC_STATS_LEN : -EOPNOTSUPP; | |
138 | } | |
139 | ||
140 | /* vnic_get_ethtool_stats - get statistics */ | |
141 | static void vnic_get_ethtool_stats(struct net_device *netdev, | |
142 | struct ethtool_stats *stats, u64 *data) | |
143 | { | |
144 | struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); | |
145 | struct opa_vnic_stats vstats; | |
146 | int i; | |
147 | ||
148 | memset(&vstats, 0, sizeof(vstats)); | |
a379d69f | 149 | spin_lock(&adapter->stats_lock); |
009b7dd4 | 150 | adapter->rn_ops->ndo_get_stats64(netdev, &vstats.netstats); |
a379d69f | 151 | spin_unlock(&adapter->stats_lock); |
009b7dd4 VN |
152 | for (i = 0; i < VNIC_STATS_LEN; i++) { |
153 | char *p = (char *)&vstats + vnic_gstrings_stats[i].stat_offset; | |
154 | ||
155 | data[i] = (vnic_gstrings_stats[i].sizeof_stat == | |
156 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | |
157 | } | |
009b7dd4 VN |
158 | } |
159 | ||
160 | /* vnic_get_strings - get strings */ | |
161 | static void vnic_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | |
162 | { | |
163 | int i; | |
164 | ||
165 | if (stringset != ETH_SS_STATS) | |
166 | return; | |
167 | ||
168 | for (i = 0; i < VNIC_STATS_LEN; i++) | |
169 | memcpy(data + i * ETH_GSTRING_LEN, | |
170 | vnic_gstrings_stats[i].stat_string, | |
171 | ETH_GSTRING_LEN); | |
172 | } | |
173 | ||
7d6f728c VN |
174 | /* ethtool ops */ |
175 | static const struct ethtool_ops opa_vnic_ethtool_ops = { | |
1bd671ab | 176 | .get_drvinfo = vnic_get_drvinfo, |
7d6f728c | 177 | .get_link = ethtool_op_get_link, |
009b7dd4 VN |
178 | .get_strings = vnic_get_strings, |
179 | .get_sset_count = vnic_get_sset_count, | |
180 | .get_ethtool_stats = vnic_get_ethtool_stats, | |
7d6f728c VN |
181 | }; |
182 | ||
183 | /* opa_vnic_set_ethtool_ops - set ethtool ops */ | |
184 | void opa_vnic_set_ethtool_ops(struct net_device *netdev) | |
185 | { | |
186 | netdev->ethtool_ops = &opa_vnic_ethtool_ops; | |
187 | } |