linux/drivers/net/fjes/fjes_ethtool.c
<<
>>
Prefs
   1/*
   2 *  FUJITSU Extended Socket Network Device driver
   3 *  Copyright (c) 2015 FUJITSU LIMITED
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, see <http://www.gnu.org/licenses/>.
  16 *
  17 * The full GNU General Public License is included in this distribution in
  18 * the file called "COPYING".
  19 *
  20 */
  21
  22/* ethtool support for fjes */
  23
  24#include <linux/vmalloc.h>
  25#include <linux/netdevice.h>
  26#include <linux/ethtool.h>
  27#include <linux/platform_device.h>
  28
  29#include "fjes.h"
  30
  31struct fjes_stats {
  32        char stat_string[ETH_GSTRING_LEN];
  33        int sizeof_stat;
  34        int stat_offset;
  35};
  36
  37#define FJES_STAT(name, stat) { \
  38        .stat_string = name, \
  39        .sizeof_stat = FIELD_SIZEOF(struct fjes_adapter, stat), \
  40        .stat_offset = offsetof(struct fjes_adapter, stat) \
  41}
  42
  43static const struct fjes_stats fjes_gstrings_stats[] = {
  44        FJES_STAT("rx_packets", stats64.rx_packets),
  45        FJES_STAT("tx_packets", stats64.tx_packets),
  46        FJES_STAT("rx_bytes", stats64.rx_bytes),
  47        FJES_STAT("tx_bytes", stats64.rx_bytes),
  48        FJES_STAT("rx_dropped", stats64.rx_dropped),
  49        FJES_STAT("tx_dropped", stats64.tx_dropped),
  50};
  51
  52static void fjes_get_ethtool_stats(struct net_device *netdev,
  53                                   struct ethtool_stats *stats, u64 *data)
  54{
  55        struct fjes_adapter *adapter = netdev_priv(netdev);
  56        char *p;
  57        int i;
  58
  59        for (i = 0; i < ARRAY_SIZE(fjes_gstrings_stats); i++) {
  60                p = (char *)adapter + fjes_gstrings_stats[i].stat_offset;
  61                data[i] = (fjes_gstrings_stats[i].sizeof_stat == sizeof(u64))
  62                        ? *(u64 *)p : *(u32 *)p;
  63        }
  64}
  65
  66static void fjes_get_strings(struct net_device *netdev,
  67                             u32 stringset, u8 *data)
  68{
  69        u8 *p = data;
  70        int i;
  71
  72        switch (stringset) {
  73        case ETH_SS_STATS:
  74                for (i = 0; i < ARRAY_SIZE(fjes_gstrings_stats); i++) {
  75                        memcpy(p, fjes_gstrings_stats[i].stat_string,
  76                               ETH_GSTRING_LEN);
  77                        p += ETH_GSTRING_LEN;
  78                }
  79                break;
  80        }
  81}
  82
  83static int fjes_get_sset_count(struct net_device *netdev, int sset)
  84{
  85        switch (sset) {
  86        case ETH_SS_STATS:
  87                return ARRAY_SIZE(fjes_gstrings_stats);
  88        default:
  89                return -EOPNOTSUPP;
  90        }
  91}
  92
  93static void fjes_get_drvinfo(struct net_device *netdev,
  94                             struct ethtool_drvinfo *drvinfo)
  95{
  96        struct fjes_adapter *adapter = netdev_priv(netdev);
  97        struct platform_device *plat_dev;
  98
  99        plat_dev = adapter->plat_dev;
 100
 101        strlcpy(drvinfo->driver, fjes_driver_name, sizeof(drvinfo->driver));
 102        strlcpy(drvinfo->version, fjes_driver_version,
 103                sizeof(drvinfo->version));
 104
 105        strlcpy(drvinfo->fw_version, "none", sizeof(drvinfo->fw_version));
 106        snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
 107                 "platform:%s", plat_dev->name);
 108}
 109
 110static int fjes_get_settings(struct net_device *netdev,
 111                             struct ethtool_cmd *ecmd)
 112{
 113        ecmd->supported = 0;
 114        ecmd->advertising = 0;
 115        ecmd->duplex = DUPLEX_FULL;
 116        ecmd->autoneg = AUTONEG_DISABLE;
 117        ecmd->transceiver = XCVR_DUMMY1;
 118        ecmd->port = PORT_NONE;
 119        ethtool_cmd_speed_set(ecmd, 20000);     /* 20Gb/s */
 120
 121        return 0;
 122}
 123
 124static const struct ethtool_ops fjes_ethtool_ops = {
 125                .get_settings           = fjes_get_settings,
 126                .get_drvinfo            = fjes_get_drvinfo,
 127                .get_ethtool_stats = fjes_get_ethtool_stats,
 128                .get_strings      = fjes_get_strings,
 129                .get_sset_count   = fjes_get_sset_count,
 130};
 131
 132void fjes_set_ethtool_ops(struct net_device *netdev)
 133{
 134        netdev->ethtool_ops = &fjes_ethtool_ops;
 135}
 136