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};
  66
  67#ifdef CONFIG_DEBUG_FS
  68
  69static int
  70qcaspi_info_show(struct seq_file *s, void *what)
  71{
  72        struct qcaspi *qca = s->private;
  73
  74        seq_printf(s, "RX buffer size   : %lu\n",
  75                   (unsigned long)qca->buffer_size);
  76
  77        seq_puts(s, "TX ring state    : ");
  78
  79        if (qca->txr.skb[qca->txr.head] == NULL)
  80                seq_puts(s, "empty");
  81        else if (qca->txr.skb[qca->txr.tail])
  82                seq_puts(s, "full");
  83        else
  84                seq_puts(s, "in use");
  85
  86        seq_puts(s, "\n");
  87
  88        seq_printf(s, "TX ring size     : %u\n",
  89                   qca->txr.size);
  90
  91        seq_printf(s, "Sync state       : %u (",
  92                   (unsigned int)qca->sync);
  93        switch (qca->sync) {
  94        case QCASPI_SYNC_UNKNOWN:
  95                seq_puts(s, "QCASPI_SYNC_UNKNOWN");
  96                break;
  97        case QCASPI_SYNC_RESET:
  98                seq_puts(s, "QCASPI_SYNC_RESET");
  99                break;
 100        case QCASPI_SYNC_READY:
 101                seq_puts(s, "QCASPI_SYNC_READY");
 102                break;
 103        default:
 104                seq_puts(s, "INVALID");
 105                break;
 106        }
 107        seq_puts(s, ")\n");
 108
 109        seq_printf(s, "IRQ              : %d\n",
 110                   qca->spi_dev->irq);
 111        seq_printf(s, "INTR REQ         : %u\n",
 112                   qca->intr_req);
 113        seq_printf(s, "INTR SVC         : %u\n",
 114                   qca->intr_svc);
 115
 116        seq_printf(s, "SPI max speed    : %lu\n",
 117                   (unsigned long)qca->spi_dev->max_speed_hz);
 118        seq_printf(s, "SPI mode         : %x\n",
 119                   qca->spi_dev->mode);
 120        seq_printf(s, "SPI chip select  : %u\n",
 121                   (unsigned int)qca->spi_dev->chip_select);
 122        seq_printf(s, "SPI legacy mode  : %u\n",
 123                   (unsigned int)qca->legacy_mode);
 124        seq_printf(s, "SPI burst length : %u\n",
 125                   (unsigned int)qca->burst_len);
 126
 127        return 0;
 128}
 129DEFINE_SHOW_ATTRIBUTE(qcaspi_info);
 130
 131void
 132qcaspi_init_device_debugfs(struct qcaspi *qca)
 133{
 134        struct dentry *device_root;
 135
 136        device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev), NULL);
 137        qca->device_root = device_root;
 138
 139        if (IS_ERR(device_root) || !device_root) {
 140                pr_warn("failed to create debugfs directory for %s\n",
 141                        dev_name(&qca->net_dev->dev));
 142                return;
 143        }
 144        debugfs_create_file("info", S_IFREG | 0444, device_root, qca,
 145                            &qcaspi_info_fops);
 146}
 147
 148void
 149qcaspi_remove_device_debugfs(struct qcaspi *qca)
 150{
 151        debugfs_remove_recursive(qca->device_root);
 152}
 153
 154#else /* CONFIG_DEBUG_FS */
 155
 156void
 157qcaspi_init_device_debugfs(struct qcaspi *qca)
 158{
 159}
 160
 161void
 162qcaspi_remove_device_debugfs(struct qcaspi *qca)
 163{
 164}
 165
 166#endif
 167
 168static void
 169qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
 170{
 171        struct qcaspi *qca = netdev_priv(dev);
 172
 173        strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
 174        strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
 175        strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
 176        strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev),
 177                sizeof(p->bus_info));
 178}
 179
 180static int
 181qcaspi_get_link_ksettings(struct net_device *dev,
 182                          struct ethtool_link_ksettings *cmd)
 183{
 184        ethtool_link_ksettings_zero_link_mode(cmd, supported);
 185        ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
 186
 187        cmd->base.speed = SPEED_10;
 188        cmd->base.duplex = DUPLEX_HALF;
 189        cmd->base.port = PORT_OTHER;
 190        cmd->base.autoneg = AUTONEG_DISABLE;
 191
 192        return 0;
 193}
 194
 195static void
 196qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
 197{
 198        struct qcaspi *qca = netdev_priv(dev);
 199        struct qcaspi_stats *st = &qca->stats;
 200
 201        memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
 202}
 203
 204static void
 205qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 206{
 207        switch (stringset) {
 208        case ETH_SS_STATS:
 209                memcpy(buf, &qcaspi_gstrings_stats,
 210                       sizeof(qcaspi_gstrings_stats));
 211                break;
 212        default:
 213                WARN_ON(1);
 214                break;
 215        }
 216}
 217
 218static int
 219qcaspi_get_sset_count(struct net_device *dev, int sset)
 220{
 221        switch (sset) {
 222        case ETH_SS_STATS:
 223                return ARRAY_SIZE(qcaspi_gstrings_stats);
 224        default:
 225                return -EINVAL;
 226        }
 227}
 228
 229static int
 230qcaspi_get_regs_len(struct net_device *dev)
 231{
 232        return sizeof(u32) * QCASPI_MAX_REGS;
 233}
 234
 235static void
 236qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 237{
 238        struct qcaspi *qca = netdev_priv(dev);
 239        u32 *regs_buff = p;
 240        unsigned int i;
 241
 242        regs->version = 1;
 243        memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
 244
 245        for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
 246                u16 offset, value;
 247
 248                qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
 249                offset = qcaspi_spi_regs[i] >> 8;
 250                regs_buff[offset] = value;
 251        }
 252}
 253
 254static void
 255qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 256{
 257        struct qcaspi *qca = netdev_priv(dev);
 258
 259        ring->rx_max_pending = 4;
 260        ring->tx_max_pending = TX_RING_MAX_LEN;
 261        ring->rx_pending = 4;
 262        ring->tx_pending = qca->txr.count;
 263}
 264
 265static int
 266qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 267{
 268        const struct net_device_ops *ops = dev->netdev_ops;
 269        struct qcaspi *qca = netdev_priv(dev);
 270
 271        if ((ring->rx_pending) ||
 272            (ring->rx_mini_pending) ||
 273            (ring->rx_jumbo_pending))
 274                return -EINVAL;
 275
 276        if (netif_running(dev))
 277                ops->ndo_stop(dev);
 278
 279        qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
 280        qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
 281
 282        if (netif_running(dev))
 283                ops->ndo_open(dev);
 284
 285        return 0;
 286}
 287
 288static const struct ethtool_ops qcaspi_ethtool_ops = {
 289        .get_drvinfo = qcaspi_get_drvinfo,
 290        .get_link = ethtool_op_get_link,
 291        .get_ethtool_stats = qcaspi_get_ethtool_stats,
 292        .get_strings = qcaspi_get_strings,
 293        .get_sset_count = qcaspi_get_sset_count,
 294        .get_regs_len = qcaspi_get_regs_len,
 295        .get_regs = qcaspi_get_regs,
 296        .get_ringparam = qcaspi_get_ringparam,
 297        .set_ringparam = qcaspi_set_ringparam,
 298        .get_link_ksettings = qcaspi_get_link_ksettings,
 299};
 300
 301void qcaspi_set_ethtool_ops(struct net_device *dev)
 302{
 303        dev->ethtool_ops = &qcaspi_ethtool_ops;
 304}
 305