linux/drivers/net/pasemi_mac_ethtool.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006-2008 PA Semi, Inc
   3 *
   4 * Ethtool hooks for the PA Semi PWRficient onchip 1G/10G Ethernet MACs
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18 */
  19
  20
  21#include <linux/netdevice.h>
  22#include <linux/ethtool.h>
  23#include <linux/pci.h>
  24#include <linux/inet_lro.h>
  25
  26#include <asm/pasemi_dma.h>
  27#include "pasemi_mac.h"
  28
  29static struct {
  30        const char str[ETH_GSTRING_LEN];
  31} ethtool_stats_keys[] = {
  32        { "rx-drops" },
  33        { "rx-bytes" },
  34        { "rx-packets" },
  35        { "rx-broadcast-packets" },
  36        { "rx-multicast-packets" },
  37        { "rx-crc-errors" },
  38        { "rx-undersize-errors" },
  39        { "rx-oversize-errors" },
  40        { "rx-short-fragment-errors" },
  41        { "rx-jabber-errors" },
  42        { "rx-64-byte-packets" },
  43        { "rx-65-127-byte-packets" },
  44        { "rx-128-255-byte-packets" },
  45        { "rx-256-511-byte-packets" },
  46        { "rx-512-1023-byte-packets" },
  47        { "rx-1024-1518-byte-packets" },
  48        { "rx-pause-frames" },
  49        { "tx-bytes" },
  50        { "tx-packets" },
  51        { "tx-broadcast-packets" },
  52        { "tx-multicast-packets" },
  53        { "tx-collisions" },
  54        { "tx-late-collisions" },
  55        { "tx-excessive-collisions" },
  56        { "tx-crc-errors" },
  57        { "tx-undersize-errors" },
  58        { "tx-oversize-errors" },
  59        { "tx-64-byte-packets" },
  60        { "tx-65-127-byte-packets" },
  61        { "tx-128-255-byte-packets" },
  62        { "tx-256-511-byte-packets" },
  63        { "tx-512-1023-byte-packets" },
  64        { "tx-1024-1518-byte-packets" },
  65};
  66
  67static int
  68pasemi_mac_ethtool_get_settings(struct net_device *netdev,
  69                               struct ethtool_cmd *cmd)
  70{
  71        struct pasemi_mac *mac = netdev_priv(netdev);
  72        struct phy_device *phydev = mac->phydev;
  73
  74        if (!phydev)
  75                return -EOPNOTSUPP;
  76
  77        return phy_ethtool_gset(phydev, cmd);
  78}
  79
  80static void
  81pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev,
  82                               struct ethtool_drvinfo *drvinfo)
  83{
  84        struct pasemi_mac *mac;
  85        mac = netdev_priv(netdev);
  86
  87        /* clear and fill out info */
  88        memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
  89        strncpy(drvinfo->driver, "pasemi_mac", 12);
  90        strcpy(drvinfo->version, "N/A");
  91        strcpy(drvinfo->fw_version, "N/A");
  92        strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32);
  93}
  94
  95static u32
  96pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
  97{
  98        struct pasemi_mac *mac = netdev_priv(netdev);
  99        return mac->msg_enable;
 100}
 101
 102static void
 103pasemi_mac_ethtool_set_msglevel(struct net_device *netdev,
 104                                u32 level)
 105{
 106        struct pasemi_mac *mac = netdev_priv(netdev);
 107        mac->msg_enable = level;
 108}
 109
 110
 111static void
 112pasemi_mac_ethtool_get_ringparam(struct net_device *netdev,
 113                                 struct ethtool_ringparam *ering)
 114{
 115        struct pasemi_mac *mac = netdev_priv(netdev);
 116
 117        ering->tx_max_pending = TX_RING_SIZE/2;
 118        ering->tx_pending = RING_USED(mac->tx)/2;
 119        ering->rx_max_pending = RX_RING_SIZE/4;
 120        ering->rx_pending = RING_USED(mac->rx)/4;
 121}
 122
 123static int pasemi_mac_get_sset_count(struct net_device *netdev, int sset)
 124{
 125        switch (sset) {
 126        case ETH_SS_STATS:
 127                return ARRAY_SIZE(ethtool_stats_keys);
 128        default:
 129                return -EOPNOTSUPP;
 130        }
 131}
 132
 133static void pasemi_mac_get_ethtool_stats(struct net_device *netdev,
 134                struct ethtool_stats *stats, u64 *data)
 135{
 136        struct pasemi_mac *mac = netdev_priv(netdev);
 137        int i;
 138
 139        data[0] = pasemi_read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if))
 140                        >> PAS_DMA_RXINT_RCMDSTA_DROPS_S;
 141        for (i = 0; i < 32; i++)
 142                data[1+i] = pasemi_read_mac_reg(mac->dma_if, PAS_MAC_RMON(i));
 143}
 144
 145static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset,
 146                                   u8 *data)
 147{
 148        memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
 149}
 150
 151const struct ethtool_ops pasemi_mac_ethtool_ops = {
 152        .get_settings           = pasemi_mac_ethtool_get_settings,
 153        .get_drvinfo            = pasemi_mac_ethtool_get_drvinfo,
 154        .get_msglevel           = pasemi_mac_ethtool_get_msglevel,
 155        .set_msglevel           = pasemi_mac_ethtool_set_msglevel,
 156        .get_link               = ethtool_op_get_link,
 157        .get_ringparam          = pasemi_mac_ethtool_get_ringparam,
 158        .get_strings            = pasemi_mac_get_strings,
 159        .get_sset_count         = pasemi_mac_get_sset_count,
 160        .get_ethtool_stats      = pasemi_mac_get_ethtool_stats,
 161};
 162
 163