linux/drivers/net/spider_net_ethtool.c
<<
>>
Prefs
   1/*
   2 * Network device driver for Cell Processor-Based Blade
   3 *
   4 * (C) Copyright IBM Corp. 2005
   5 *
   6 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
   7 *           Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2, or (at your option)
  12 * any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22 */
  23
  24#include <linux/netdevice.h>
  25#include <linux/ethtool.h>
  26#include <linux/pci.h>
  27
  28#include "spider_net.h"
  29
  30
  31static struct {
  32        const char str[ETH_GSTRING_LEN];
  33} ethtool_stats_keys[] = {
  34        { "tx_packets" },
  35        { "tx_bytes" },
  36        { "rx_packets" },
  37        { "rx_bytes" },
  38        { "tx_errors" },
  39        { "tx_dropped" },
  40        { "rx_dropped" },
  41        { "rx_descriptor_error" },
  42        { "tx_timeouts" },
  43        { "alloc_rx_skb_error" },
  44        { "rx_iommu_map_error" },
  45        { "tx_iommu_map_error" },
  46        { "rx_desc_unk_state" },
  47};
  48
  49static int
  50spider_net_ethtool_get_settings(struct net_device *netdev,
  51                               struct ethtool_cmd *cmd)
  52{
  53        struct spider_net_card *card;
  54        card = netdev_priv(netdev);
  55
  56        cmd->supported   = (SUPPORTED_1000baseT_Full |
  57                             SUPPORTED_FIBRE);
  58        cmd->advertising = (ADVERTISED_1000baseT_Full |
  59                             ADVERTISED_FIBRE);
  60        cmd->port = PORT_FIBRE;
  61        cmd->speed = card->phy.speed;
  62        cmd->duplex = DUPLEX_FULL;
  63
  64        return 0;
  65}
  66
  67static void
  68spider_net_ethtool_get_drvinfo(struct net_device *netdev,
  69                               struct ethtool_drvinfo *drvinfo)
  70{
  71        struct spider_net_card *card;
  72        card = netdev_priv(netdev);
  73
  74        /* clear and fill out info */
  75        memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
  76        strncpy(drvinfo->driver, spider_net_driver_name, 32);
  77        strncpy(drvinfo->version, VERSION, 32);
  78        strcpy(drvinfo->fw_version, "no information");
  79        strncpy(drvinfo->bus_info, pci_name(card->pdev), 32);
  80}
  81
  82static void
  83spider_net_ethtool_get_wol(struct net_device *netdev,
  84                           struct ethtool_wolinfo *wolinfo)
  85{
  86        /* no support for wol */
  87        wolinfo->supported = 0;
  88        wolinfo->wolopts = 0;
  89}
  90
  91static u32
  92spider_net_ethtool_get_msglevel(struct net_device *netdev)
  93{
  94        struct spider_net_card *card;
  95        card = netdev_priv(netdev);
  96        return card->msg_enable;
  97}
  98
  99static void
 100spider_net_ethtool_set_msglevel(struct net_device *netdev,
 101                                u32 level)
 102{
 103        struct spider_net_card *card;
 104        card = netdev_priv(netdev);
 105        card->msg_enable = level;
 106}
 107
 108static int
 109spider_net_ethtool_nway_reset(struct net_device *netdev)
 110{
 111        if (netif_running(netdev)) {
 112                spider_net_stop(netdev);
 113                spider_net_open(netdev);
 114        }
 115        return 0;
 116}
 117
 118static u32
 119spider_net_ethtool_get_rx_csum(struct net_device *netdev)
 120{
 121        struct spider_net_card *card = netdev_priv(netdev);
 122
 123        return card->options.rx_csum;
 124}
 125
 126static int
 127spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n)
 128{
 129        struct spider_net_card *card = netdev_priv(netdev);
 130
 131        card->options.rx_csum = n;
 132        return 0;
 133}
 134
 135
 136static void
 137spider_net_ethtool_get_ringparam(struct net_device *netdev,
 138                                 struct ethtool_ringparam *ering)
 139{
 140        struct spider_net_card *card = netdev_priv(netdev);
 141
 142        ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX;
 143        ering->tx_pending = card->tx_chain.num_desc;
 144        ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX;
 145        ering->rx_pending = card->rx_chain.num_desc;
 146}
 147
 148static int spider_net_get_sset_count(struct net_device *netdev, int sset)
 149{
 150        switch (sset) {
 151        case ETH_SS_STATS:
 152                return ARRAY_SIZE(ethtool_stats_keys);
 153        default:
 154                return -EOPNOTSUPP;
 155        }
 156}
 157
 158static void spider_net_get_ethtool_stats(struct net_device *netdev,
 159                struct ethtool_stats *stats, u64 *data)
 160{
 161        struct spider_net_card *card = netdev_priv(netdev);
 162
 163        data[0] = netdev->stats.tx_packets;
 164        data[1] = netdev->stats.tx_bytes;
 165        data[2] = netdev->stats.rx_packets;
 166        data[3] = netdev->stats.rx_bytes;
 167        data[4] = netdev->stats.tx_errors;
 168        data[5] = netdev->stats.tx_dropped;
 169        data[6] = netdev->stats.rx_dropped;
 170        data[7] = card->spider_stats.rx_desc_error;
 171        data[8] = card->spider_stats.tx_timeouts;
 172        data[9] = card->spider_stats.alloc_rx_skb_error;
 173        data[10] = card->spider_stats.rx_iommu_map_error;
 174        data[11] = card->spider_stats.tx_iommu_map_error;
 175        data[12] = card->spider_stats.rx_desc_unk_state;
 176}
 177
 178static void spider_net_get_strings(struct net_device *netdev, u32 stringset,
 179                                   u8 *data)
 180{
 181        memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
 182}
 183
 184const struct ethtool_ops spider_net_ethtool_ops = {
 185        .get_settings           = spider_net_ethtool_get_settings,
 186        .get_drvinfo            = spider_net_ethtool_get_drvinfo,
 187        .get_wol                = spider_net_ethtool_get_wol,
 188        .get_msglevel           = spider_net_ethtool_get_msglevel,
 189        .set_msglevel           = spider_net_ethtool_set_msglevel,
 190        .get_link               = ethtool_op_get_link,
 191        .nway_reset             = spider_net_ethtool_nway_reset,
 192        .get_rx_csum            = spider_net_ethtool_get_rx_csum,
 193        .set_rx_csum            = spider_net_ethtool_set_rx_csum,
 194        .set_tx_csum            = ethtool_op_set_tx_csum,
 195        .get_ringparam          = spider_net_ethtool_get_ringparam,
 196        .get_strings            = spider_net_get_strings,
 197        .get_sset_count         = spider_net_get_sset_count,
 198        .get_ethtool_stats      = spider_net_get_ethtool_stats,
 199};
 200
 201