linux/drivers/net/ethernet/pasemi/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 int
  81pasemi_mac_ethtool_set_settings(struct net_device *netdev,
  82                               struct ethtool_cmd *cmd)
  83{
  84        struct pasemi_mac *mac = netdev_priv(netdev);
  85        struct phy_device *phydev = mac->phydev;
  86
  87        if (!phydev)
  88                return -EOPNOTSUPP;
  89
  90        return phy_ethtool_sset(phydev, cmd);
  91}
  92
  93static u32
  94pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
  95{
  96        struct pasemi_mac *mac = netdev_priv(netdev);
  97        return mac->msg_enable;
  98}
  99
 100static void
 101pasemi_mac_ethtool_set_msglevel(struct net_device *netdev,
 102                                u32 level)
 103{
 104        struct pasemi_mac *mac = netdev_priv(netdev);
 105        mac->msg_enable = level;
 106}
 107
 108
 109static void
 110pasemi_mac_ethtool_get_ringparam(struct net_device *netdev,
 111                                 struct ethtool_ringparam *ering)
 112{
 113        struct pasemi_mac *mac = netdev_priv(netdev);
 114
 115        ering->tx_max_pending = TX_RING_SIZE/2;
 116        ering->tx_pending = RING_USED(mac->tx)/2;
 117        ering->rx_max_pending = RX_RING_SIZE/4;
 118        ering->rx_pending = RING_USED(mac->rx)/4;
 119}
 120
 121static int pasemi_mac_get_sset_count(struct net_device *netdev, int sset)
 122{
 123        switch (sset) {
 124        case ETH_SS_STATS:
 125                return ARRAY_SIZE(ethtool_stats_keys);
 126        default:
 127                return -EOPNOTSUPP;
 128        }
 129}
 130
 131static void pasemi_mac_get_ethtool_stats(struct net_device *netdev,
 132                struct ethtool_stats *stats, u64 *data)
 133{
 134        struct pasemi_mac *mac = netdev_priv(netdev);
 135        int i;
 136
 137        data[0] = pasemi_read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if))
 138                        >> PAS_DMA_RXINT_RCMDSTA_DROPS_S;
 139        for (i = 0; i < 32; i++)
 140                data[1+i] = pasemi_read_mac_reg(mac->dma_if, PAS_MAC_RMON(i));
 141}
 142
 143static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset,
 144                                   u8 *data)
 145{
 146        memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
 147}
 148
 149const struct ethtool_ops pasemi_mac_ethtool_ops = {
 150        .get_settings           = pasemi_mac_ethtool_get_settings,
 151        .set_settings           = pasemi_mac_ethtool_set_settings,
 152        .get_msglevel           = pasemi_mac_ethtool_get_msglevel,
 153        .set_msglevel           = pasemi_mac_ethtool_set_msglevel,
 154        .get_link               = ethtool_op_get_link,
 155        .get_ringparam          = pasemi_mac_ethtool_get_ringparam,
 156        .get_strings            = pasemi_mac_get_strings,
 157        .get_sset_count         = pasemi_mac_get_sset_count,
 158        .get_ethtool_stats      = pasemi_mac_get_ethtool_stats,
 159};
 160
 161