cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qca_debug.c (7424B)


      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		     struct kernel_ethtool_ringparam *kernel_ring,
    251		     struct netlink_ext_ack *extack)
    252{
    253	struct qcaspi *qca = netdev_priv(dev);
    254
    255	ring->rx_max_pending = 4;
    256	ring->tx_max_pending = TX_RING_MAX_LEN;
    257	ring->rx_pending = 4;
    258	ring->tx_pending = qca->txr.count;
    259}
    260
    261static int
    262qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring,
    263		     struct kernel_ethtool_ringparam *kernel_ring,
    264		     struct netlink_ext_ack *extack)
    265{
    266	const struct net_device_ops *ops = dev->netdev_ops;
    267	struct qcaspi *qca = netdev_priv(dev);
    268
    269	if ((ring->rx_pending) ||
    270	    (ring->rx_mini_pending) ||
    271	    (ring->rx_jumbo_pending))
    272		return -EINVAL;
    273
    274	if (netif_running(dev))
    275		ops->ndo_stop(dev);
    276
    277	qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
    278	qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
    279
    280	if (netif_running(dev))
    281		ops->ndo_open(dev);
    282
    283	return 0;
    284}
    285
    286static const struct ethtool_ops qcaspi_ethtool_ops = {
    287	.get_drvinfo = qcaspi_get_drvinfo,
    288	.get_link = ethtool_op_get_link,
    289	.get_ethtool_stats = qcaspi_get_ethtool_stats,
    290	.get_strings = qcaspi_get_strings,
    291	.get_sset_count = qcaspi_get_sset_count,
    292	.get_regs_len = qcaspi_get_regs_len,
    293	.get_regs = qcaspi_get_regs,
    294	.get_ringparam = qcaspi_get_ringparam,
    295	.set_ringparam = qcaspi_set_ringparam,
    296	.get_link_ksettings = qcaspi_get_link_ksettings,
    297};
    298
    299void qcaspi_set_ethtool_ops(struct net_device *dev)
    300{
    301	dev->ethtool_ops = &qcaspi_ethtool_ops;
    302}