linux/drivers/net/ethernet/qualcomm/qca_debug.c
<<
>>
Prefs
   1/*
   2 *   Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
   3 *   Copyright (c) 2014, I2SE GmbH
   4 *
   5 *   Permission to use, copy, modify, and/or distribute this software
   6 *   for any purpose with or without fee is hereby granted, provided
   7 *   that the above copyright notice and this permission notice appear
   8 *   in all copies.
   9 *
  10 *   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11 *   WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12 *   WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  13 *   THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  14 *   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15 *   LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  16 *   NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17 *   CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18 */
  19
  20/*   This file contains debugging routines for use in the QCA7K driver.
  21 */
  22
  23#include <linux/debugfs.h>
  24#include <linux/ethtool.h>
  25#include <linux/seq_file.h>
  26#include <linux/types.h>
  27
  28#include "qca_7k.h"
  29#include "qca_debug.h"
  30
  31#define QCASPI_MAX_REGS 0x20
  32
  33static const u16 qcaspi_spi_regs[] = {
  34        SPI_REG_BFR_SIZE,
  35        SPI_REG_WRBUF_SPC_AVA,
  36        SPI_REG_RDBUF_BYTE_AVA,
  37        SPI_REG_SPI_CONFIG,
  38        SPI_REG_SPI_STATUS,
  39        SPI_REG_INTR_CAUSE,
  40        SPI_REG_INTR_ENABLE,
  41        SPI_REG_RDBUF_WATERMARK,
  42        SPI_REG_WRBUF_WATERMARK,
  43        SPI_REG_SIGNATURE,
  44        SPI_REG_ACTION_CTRL
  45};
  46
  47/* The order of these strings must match the order of the fields in
  48 * struct qcaspi_stats
  49 * See qca_spi.h
  50 */
  51static const char qcaspi_gstrings_stats[][ETH_GSTRING_LEN] = {
  52        "Triggered resets",
  53        "Device resets",
  54        "Reset timeouts",
  55        "Read errors",
  56        "Write errors",
  57        "Read buffer errors",
  58        "Write buffer errors",
  59        "Out of memory",
  60        "Write buffer misses",
  61        "Transmit ring full",
  62        "SPI errors",
  63        "Write verify errors",
  64        "Buffer available errors",
  65        "Bad signature",
  66};
  67
  68#ifdef CONFIG_DEBUG_FS
  69
  70static int
  71qcaspi_info_show(struct seq_file *s, void *what)
  72{
  73        struct qcaspi *qca = s->private;
  74
  75        seq_printf(s, "RX buffer size   : %lu\n",
  76                   (unsigned long)qca->buffer_size);
  77
  78        seq_puts(s, "TX ring state    : ");
  79
  80        if (qca->txr.skb[qca->txr.head] == NULL)
  81                seq_puts(s, "empty");
  82        else if (qca->txr.skb[qca->txr.tail])
  83                seq_puts(s, "full");
  84        else
  85                seq_puts(s, "in use");
  86
  87        seq_puts(s, "\n");
  88
  89        seq_printf(s, "TX ring size     : %u\n",
  90                   qca->txr.size);
  91
  92        seq_printf(s, "Sync state       : %u (",
  93                   (unsigned int)qca->sync);
  94        switch (qca->sync) {
  95        case QCASPI_SYNC_UNKNOWN:
  96                seq_puts(s, "QCASPI_SYNC_UNKNOWN");
  97                break;
  98        case QCASPI_SYNC_RESET:
  99                seq_puts(s, "QCASPI_SYNC_RESET");
 100                break;
 101        case QCASPI_SYNC_READY:
 102                seq_puts(s, "QCASPI_SYNC_READY");
 103                break;
 104        default:
 105                seq_puts(s, "INVALID");
 106                break;
 107        }
 108        seq_puts(s, ")\n");
 109
 110        seq_printf(s, "IRQ              : %d\n",
 111                   qca->spi_dev->irq);
 112        seq_printf(s, "INTR REQ         : %u\n",
 113                   qca->intr_req);
 114        seq_printf(s, "INTR SVC         : %u\n",
 115                   qca->intr_svc);
 116
 117        seq_printf(s, "SPI max speed    : %lu\n",
 118                   (unsigned long)qca->spi_dev->max_speed_hz);
 119        seq_printf(s, "SPI mode         : %x\n",
 120                   qca->spi_dev->mode);
 121        seq_printf(s, "SPI chip select  : %u\n",
 122                   (unsigned int)qca->spi_dev->chip_select);
 123        seq_printf(s, "SPI legacy mode  : %u\n",
 124                   (unsigned int)qca->legacy_mode);
 125        seq_printf(s, "SPI burst length : %u\n",
 126                   (unsigned int)qca->burst_len);
 127
 128        return 0;
 129}
 130DEFINE_SHOW_ATTRIBUTE(qcaspi_info);
 131
 132void
 133qcaspi_init_device_debugfs(struct qcaspi *qca)
 134{
 135        qca->device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev),
 136                                              NULL);
 137
 138        debugfs_create_file("info", S_IFREG | 0444, qca->device_root, qca,
 139                            &qcaspi_info_fops);
 140}
 141
 142void
 143qcaspi_remove_device_debugfs(struct qcaspi *qca)
 144{
 145        debugfs_remove_recursive(qca->device_root);
 146}
 147
 148#else /* CONFIG_DEBUG_FS */
 149
 150void
 151qcaspi_init_device_debugfs(struct qcaspi *qca)
 152{
 153}
 154
 155void
 156qcaspi_remove_device_debugfs(struct qcaspi *qca)
 157{
 158}
 159
 160#endif
 161
 162static void
 163qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
 164{
 165        struct qcaspi *qca = netdev_priv(dev);
 166
 167        strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
 168        strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
 169        strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
 170        strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev),
 171                sizeof(p->bus_info));
 172}
 173
 174static int
 175qcaspi_get_link_ksettings(struct net_device *dev,
 176                          struct ethtool_link_ksettings *cmd)
 177{
 178        ethtool_link_ksettings_zero_link_mode(cmd, supported);
 179        ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
 180
 181        cmd->base.speed = SPEED_10;
 182        cmd->base.duplex = DUPLEX_HALF;
 183        cmd->base.port = PORT_OTHER;
 184        cmd->base.autoneg = AUTONEG_DISABLE;
 185
 186        return 0;
 187}
 188
 189static void
 190qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
 191{
 192        struct qcaspi *qca = netdev_priv(dev);
 193        struct qcaspi_stats *st = &qca->stats;
 194
 195        memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
 196}
 197
 198static void
 199qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 200{
 201        switch (stringset) {
 202        case ETH_SS_STATS:
 203                memcpy(buf, &qcaspi_gstrings_stats,
 204                       sizeof(qcaspi_gstrings_stats));
 205                break;
 206        default:
 207                WARN_ON(1);
 208                break;
 209        }
 210}
 211
 212static int
 213qcaspi_get_sset_count(struct net_device *dev, int sset)
 214{
 215        switch (sset) {
 216        case ETH_SS_STATS:
 217                return ARRAY_SIZE(qcaspi_gstrings_stats);
 218        default:
 219                return -EINVAL;
 220        }
 221}
 222
 223static int
 224qcaspi_get_regs_len(struct net_device *dev)
 225{
 226        return sizeof(u32) * QCASPI_MAX_REGS;
 227}
 228
 229static void
 230qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 231{
 232        struct qcaspi *qca = netdev_priv(dev);
 233        u32 *regs_buff = p;
 234        unsigned int i;
 235
 236        regs->version = 1;
 237        memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
 238
 239        for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
 240                u16 offset, value;
 241
 242                qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
 243                offset = qcaspi_spi_regs[i] >> 8;
 244                regs_buff[offset] = value;
 245        }
 246}
 247
 248static void
 249qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 250{
 251        struct qcaspi *qca = netdev_priv(dev);
 252
 253        ring->rx_max_pending = 4;
 254        ring->tx_max_pending = TX_RING_MAX_LEN;
 255        ring->rx_pending = 4;
 256        ring->tx_pending = qca->txr.count;
 257}
 258
 259static int
 260qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 261{
 262        const struct net_device_ops *ops = dev->netdev_ops;
 263        struct qcaspi *qca = netdev_priv(dev);
 264
 265        if ((ring->rx_pending) ||
 266            (ring->rx_mini_pending) ||
 267            (ring->rx_jumbo_pending))
 268                return -EINVAL;
 269
 270        if (netif_running(dev))
 271                ops->ndo_stop(dev);
 272
 273        qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
 274        qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
 275
 276        if (netif_running(dev))
 277                ops->ndo_open(dev);
 278
 279        return 0;
 280}
 281
 282static const struct ethtool_ops qcaspi_ethtool_ops = {
 283        .get_drvinfo = qcaspi_get_drvinfo,
 284        .get_link = ethtool_op_get_link,
 285        .get_ethtool_stats = qcaspi_get_ethtool_stats,
 286        .get_strings = qcaspi_get_strings,
 287        .get_sset_count = qcaspi_get_sset_count,
 288        .get_regs_len = qcaspi_get_regs_len,
 289        .get_regs = qcaspi_get_regs,
 290        .get_ringparam = qcaspi_get_ringparam,
 291        .set_ringparam = qcaspi_set_ringparam,
 292        .get_link_ksettings = qcaspi_get_link_ksettings,
 293};
 294
 295void qcaspi_set_ethtool_ops(struct net_device *dev)
 296{
 297        dev->ethtool_ops = &qcaspi_ethtool_ops;
 298}
 299