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 */ 1241bd671abSVishwanathapura, Niranjana static void vnic_get_drvinfo(struct net_device *netdev, 1251bd671abSVishwanathapura, Niranjana struct ethtool_drvinfo *drvinfo) 1261bd671abSVishwanathapura, Niranjana { 1271bd671abSVishwanathapura, Niranjana strlcpy(drvinfo->driver, opa_vnic_driver_name, sizeof(drvinfo->driver)); 1281bd671abSVishwanathapura, Niranjana strlcpy(drvinfo->version, opa_vnic_driver_version, 1291bd671abSVishwanathapura, Niranjana sizeof(drvinfo->version)); 1301bd671abSVishwanathapura, Niranjana strlcpy(drvinfo->bus_info, dev_name(netdev->dev.parent), 1311bd671abSVishwanathapura, Niranjana sizeof(drvinfo->bus_info)); 1321bd671abSVishwanathapura, Niranjana } 1331bd671abSVishwanathapura, Niranjana 134009b7dd4SVishwanathapura, Niranjana /* vnic_get_sset_count - get string set count */ 135009b7dd4SVishwanathapura, Niranjana static int vnic_get_sset_count(struct net_device *netdev, int sset) 136009b7dd4SVishwanathapura, Niranjana { 137009b7dd4SVishwanathapura, Niranjana return (sset == ETH_SS_STATS) ? VNIC_STATS_LEN : -EOPNOTSUPP; 138009b7dd4SVishwanathapura, Niranjana } 139009b7dd4SVishwanathapura, Niranjana 140009b7dd4SVishwanathapura, Niranjana /* vnic_get_ethtool_stats - get statistics */ 141009b7dd4SVishwanathapura, Niranjana static void vnic_get_ethtool_stats(struct net_device *netdev, 142009b7dd4SVishwanathapura, Niranjana struct ethtool_stats *stats, u64 *data) 143009b7dd4SVishwanathapura, Niranjana { 144009b7dd4SVishwanathapura, Niranjana struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 145009b7dd4SVishwanathapura, Niranjana struct opa_vnic_stats vstats; 146009b7dd4SVishwanathapura, Niranjana int i; 147009b7dd4SVishwanathapura, Niranjana 148009b7dd4SVishwanathapura, Niranjana memset(&vstats, 0, sizeof(vstats)); 149a379d69fSVishwanathapura, Niranjana spin_lock(&adapter->stats_lock); 150009b7dd4SVishwanathapura, Niranjana adapter->rn_ops->ndo_get_stats64(netdev, &vstats.netstats); 151a379d69fSVishwanathapura, Niranjana spin_unlock(&adapter->stats_lock); 152009b7dd4SVishwanathapura, Niranjana for (i = 0; i < VNIC_STATS_LEN; i++) { 153009b7dd4SVishwanathapura, Niranjana char *p = (char *)&vstats + vnic_gstrings_stats[i].stat_offset; 154009b7dd4SVishwanathapura, Niranjana 155009b7dd4SVishwanathapura, Niranjana data[i] = (vnic_gstrings_stats[i].sizeof_stat == 156009b7dd4SVishwanathapura, Niranjana sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 157009b7dd4SVishwanathapura, Niranjana } 158009b7dd4SVishwanathapura, Niranjana } 159009b7dd4SVishwanathapura, Niranjana 160009b7dd4SVishwanathapura, Niranjana /* vnic_get_strings - get strings */ 161009b7dd4SVishwanathapura, Niranjana static void vnic_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 162009b7dd4SVishwanathapura, Niranjana { 163009b7dd4SVishwanathapura, Niranjana int i; 164009b7dd4SVishwanathapura, Niranjana 165009b7dd4SVishwanathapura, Niranjana if (stringset != ETH_SS_STATS) 166009b7dd4SVishwanathapura, Niranjana return; 167009b7dd4SVishwanathapura, Niranjana 168009b7dd4SVishwanathapura, Niranjana for (i = 0; i < VNIC_STATS_LEN; i++) 169009b7dd4SVishwanathapura, Niranjana memcpy(data + i * ETH_GSTRING_LEN, 170009b7dd4SVishwanathapura, Niranjana vnic_gstrings_stats[i].stat_string, 171009b7dd4SVishwanathapura, Niranjana ETH_GSTRING_LEN); 172009b7dd4SVishwanathapura, Niranjana } 173009b7dd4SVishwanathapura, Niranjana 1747d6f728cSVishwanathapura, Niranjana /* ethtool ops */ 1757d6f728cSVishwanathapura, Niranjana static const struct ethtool_ops opa_vnic_ethtool_ops = { 1761bd671abSVishwanathapura, Niranjana .get_drvinfo = vnic_get_drvinfo, 1777d6f728cSVishwanathapura, Niranjana .get_link = ethtool_op_get_link, 178009b7dd4SVishwanathapura, Niranjana .get_strings = vnic_get_strings, 179009b7dd4SVishwanathapura, Niranjana .get_sset_count = vnic_get_sset_count, 180009b7dd4SVishwanathapura, Niranjana .get_ethtool_stats = vnic_get_ethtool_stats, 1817d6f728cSVishwanathapura, Niranjana }; 1827d6f728cSVishwanathapura, Niranjana 1837d6f728cSVishwanathapura, Niranjana /* opa_vnic_set_ethtool_ops - set ethtool ops */ 1847d6f728cSVishwanathapura, Niranjana void opa_vnic_set_ethtool_ops(struct net_device *netdev) 1857d6f728cSVishwanathapura, Niranjana { 1867d6f728cSVishwanathapura, Niranjana netdev->ethtool_ops = &opa_vnic_ethtool_ops; 1877d6f728cSVishwanathapura, Niranjana } 188