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