aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Wahren <stefan.wahren@i2se.com>2014-09-26 18:21:21 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-29 00:23:52 -0400
commit291ab06ecf6765aa0c73332b745ffb3a44ed30c6 (patch)
tree447d59cec4dcfa26ecf9aa6dbf11c9bd62332241
parent7d50df8f72088eadde87e771c4b2f30bfb3688a0 (diff)
net: qualcomm: new Ethernet over SPI driver for QCA7000
This patch adds the Ethernet over SPI driver for the Qualcomm QCA7000 HomePlug GreenPHY. Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/Kconfig1
-rw-r--r--drivers/net/ethernet/Makefile1
-rw-r--r--drivers/net/ethernet/qualcomm/Kconfig30
-rw-r--r--drivers/net/ethernet/qualcomm/Makefile6
-rw-r--r--drivers/net/ethernet/qualcomm/qca_7k.c149
-rw-r--r--drivers/net/ethernet/qualcomm/qca_7k.h72
-rw-r--r--drivers/net/ethernet/qualcomm/qca_debug.c311
-rw-r--r--drivers/net/ethernet/qualcomm/qca_debug.h34
-rw-r--r--drivers/net/ethernet/qualcomm/qca_framing.c156
-rw-r--r--drivers/net/ethernet/qualcomm/qca_framing.h134
-rw-r--r--drivers/net/ethernet/qualcomm/qca_spi.c993
-rw-r--r--drivers/net/ethernet/qualcomm/qca_spi.h114
12 files changed, 2001 insertions, 0 deletions
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index dc7406c81c45..0005e3792e6d 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -150,6 +150,7 @@ config ETHOC
150source "drivers/net/ethernet/packetengines/Kconfig" 150source "drivers/net/ethernet/packetengines/Kconfig"
151source "drivers/net/ethernet/pasemi/Kconfig" 151source "drivers/net/ethernet/pasemi/Kconfig"
152source "drivers/net/ethernet/qlogic/Kconfig" 152source "drivers/net/ethernet/qlogic/Kconfig"
153source "drivers/net/ethernet/qualcomm/Kconfig"
153source "drivers/net/ethernet/realtek/Kconfig" 154source "drivers/net/ethernet/realtek/Kconfig"
154source "drivers/net/ethernet/renesas/Kconfig" 155source "drivers/net/ethernet/renesas/Kconfig"
155source "drivers/net/ethernet/rdc/Kconfig" 156source "drivers/net/ethernet/rdc/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 224a01877149..153bf2dd9fad 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_ETHOC) += ethoc.o
60obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/ 60obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/
61obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ 61obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
62obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ 62obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
63obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/
63obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ 64obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
64obj-$(CONFIG_SH_ETH) += renesas/ 65obj-$(CONFIG_SH_ETH) += renesas/
65obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ 66obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
new file mode 100644
index 000000000000..f3a47147937d
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/Kconfig
@@ -0,0 +1,30 @@
1#
2# Qualcomm network device configuration
3#
4
5config NET_VENDOR_QUALCOMM
6 bool "Qualcomm devices"
7 default y
8 depends on SPI_MASTER && OF_GPIO
9 ---help---
10 If you have a network (Ethernet) card belonging to this class, say Y
11 and read the Ethernet-HOWTO, available from
12 <http://www.tldp.org/docs.html#howto>.
13
14 Note that the answer to this question doesn't directly affect the
15 kernel: saying N will just cause the configurator to skip all
16 the questions about Qualcomm cards. If you say Y, you will be asked
17 for your specific card in the following questions.
18
19if NET_VENDOR_QUALCOMM
20
21config QCA7000
22 tristate "Qualcomm Atheros QCA7000 support"
23 depends on SPI_MASTER && OF_GPIO
24 ---help---
25 This SPI protocol driver supports the Qualcomm Atheros QCA7000.
26
27 To compile this driver as a module, choose M here. The module
28 will be called qcaspi.
29
30endif # NET_VENDOR_QUALCOMM
diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile
new file mode 100644
index 000000000000..9da2d75db700
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Qualcomm network device drivers.
3#
4
5obj-$(CONFIG_QCA7000) += qcaspi.o
6qcaspi-objs := qca_spi.o qca_framing.o qca_7k.o qca_debug.o
diff --git a/drivers/net/ethernet/qualcomm/qca_7k.c b/drivers/net/ethernet/qualcomm/qca_7k.c
new file mode 100644
index 000000000000..f0066fbb44a6
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_7k.c
@@ -0,0 +1,149 @@
1/*
2 *
3 * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
4 * Copyright (c) 2014, I2SE GmbH
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose with or without fee is hereby granted, provided
8 * that the above copyright notice and this permission notice appear
9 * in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14 * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
15 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *
20 */
21
22/* This module implements the Qualcomm Atheros SPI protocol for
23 * kernel-based SPI device.
24 */
25
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/spi/spi.h>
30#include <linux/version.h>
31
32#include "qca_7k.h"
33
34void
35qcaspi_spi_error(struct qcaspi *qca)
36{
37 if (qca->sync != QCASPI_SYNC_READY)
38 return;
39
40 netdev_err(qca->net_dev, "spi error\n");
41 qca->sync = QCASPI_SYNC_UNKNOWN;
42 qca->stats.spi_err++;
43}
44
45int
46qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result)
47{
48 __be16 rx_data;
49 __be16 tx_data;
50 struct spi_transfer *transfer;
51 struct spi_message *msg;
52 int ret;
53
54 tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg);
55
56 if (qca->legacy_mode) {
57 msg = &qca->spi_msg1;
58 transfer = &qca->spi_xfer1;
59 transfer->tx_buf = &tx_data;
60 transfer->rx_buf = NULL;
61 transfer->len = QCASPI_CMD_LEN;
62 spi_sync(qca->spi_dev, msg);
63 } else {
64 msg = &qca->spi_msg2;
65 transfer = &qca->spi_xfer2[0];
66 transfer->tx_buf = &tx_data;
67 transfer->rx_buf = NULL;
68 transfer->len = QCASPI_CMD_LEN;
69 transfer = &qca->spi_xfer2[1];
70 }
71 transfer->tx_buf = NULL;
72 transfer->rx_buf = &rx_data;
73 transfer->len = QCASPI_CMD_LEN;
74 ret = spi_sync(qca->spi_dev, msg);
75
76 if (!ret)
77 ret = msg->status;
78
79 if (ret)
80 qcaspi_spi_error(qca);
81 else
82 *result = be16_to_cpu(rx_data);
83
84 return ret;
85}
86
87int
88qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value)
89{
90 __be16 tx_data[2];
91 struct spi_transfer *transfer;
92 struct spi_message *msg;
93 int ret;
94
95 tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg);
96 tx_data[1] = cpu_to_be16(value);
97
98 if (qca->legacy_mode) {
99 msg = &qca->spi_msg1;
100 transfer = &qca->spi_xfer1;
101 transfer->tx_buf = &tx_data[0];
102 transfer->rx_buf = NULL;
103 transfer->len = QCASPI_CMD_LEN;
104 spi_sync(qca->spi_dev, msg);
105 } else {
106 msg = &qca->spi_msg2;
107 transfer = &qca->spi_xfer2[0];
108 transfer->tx_buf = &tx_data[0];
109 transfer->rx_buf = NULL;
110 transfer->len = QCASPI_CMD_LEN;
111 transfer = &qca->spi_xfer2[1];
112 }
113 transfer->tx_buf = &tx_data[1];
114 transfer->rx_buf = NULL;
115 transfer->len = QCASPI_CMD_LEN;
116 ret = spi_sync(qca->spi_dev, msg);
117
118 if (!ret)
119 ret = msg->status;
120
121 if (ret)
122 qcaspi_spi_error(qca);
123
124 return ret;
125}
126
127int
128qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd)
129{
130 __be16 tx_data;
131 struct spi_message *msg = &qca->spi_msg1;
132 struct spi_transfer *transfer = &qca->spi_xfer1;
133 int ret;
134
135 tx_data = cpu_to_be16(cmd);
136 transfer->len = sizeof(tx_data);
137 transfer->tx_buf = &tx_data;
138 transfer->rx_buf = NULL;
139
140 ret = spi_sync(qca->spi_dev, msg);
141
142 if (!ret)
143 ret = msg->status;
144
145 if (ret)
146 qcaspi_spi_error(qca);
147
148 return ret;
149}
diff --git a/drivers/net/ethernet/qualcomm/qca_7k.h b/drivers/net/ethernet/qualcomm/qca_7k.h
new file mode 100644
index 000000000000..1cad851ee507
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_7k.h
@@ -0,0 +1,72 @@
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
21/* Qualcomm Atheros SPI register definition.
22 *
23 * This module is designed to define the Qualcomm Atheros SPI
24 * register placeholders.
25 */
26
27#ifndef _QCA_7K_H
28#define _QCA_7K_H
29
30#include <linux/types.h>
31
32#include "qca_spi.h"
33
34#define QCA7K_SPI_READ (1 << 15)
35#define QCA7K_SPI_WRITE (0 << 15)
36#define QCA7K_SPI_INTERNAL (1 << 14)
37#define QCA7K_SPI_EXTERNAL (0 << 14)
38
39#define QCASPI_CMD_LEN 2
40#define QCASPI_HW_PKT_LEN 4
41#define QCASPI_HW_BUF_LEN 0xC5B
42
43/* SPI registers; */
44#define SPI_REG_BFR_SIZE 0x0100
45#define SPI_REG_WRBUF_SPC_AVA 0x0200
46#define SPI_REG_RDBUF_BYTE_AVA 0x0300
47#define SPI_REG_SPI_CONFIG 0x0400
48#define SPI_REG_SPI_STATUS 0x0500
49#define SPI_REG_INTR_CAUSE 0x0C00
50#define SPI_REG_INTR_ENABLE 0x0D00
51#define SPI_REG_RDBUF_WATERMARK 0x1200
52#define SPI_REG_WRBUF_WATERMARK 0x1300
53#define SPI_REG_SIGNATURE 0x1A00
54#define SPI_REG_ACTION_CTRL 0x1B00
55
56/* SPI_CONFIG register definition; */
57#define QCASPI_SLAVE_RESET_BIT (1 << 6)
58
59/* INTR_CAUSE/ENABLE register definition. */
60#define SPI_INT_WRBUF_BELOW_WM (1 << 10)
61#define SPI_INT_CPU_ON (1 << 6)
62#define SPI_INT_ADDR_ERR (1 << 3)
63#define SPI_INT_WRBUF_ERR (1 << 2)
64#define SPI_INT_RDBUF_ERR (1 << 1)
65#define SPI_INT_PKT_AVLBL (1 << 0)
66
67void qcaspi_spi_error(struct qcaspi *qca);
68int qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result);
69int qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value);
70int qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd);
71
72#endif /* _QCA_7K_H */
diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c
new file mode 100644
index 000000000000..8e28234dddad
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_debug.c
@@ -0,0 +1,311 @@
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};
64
65#ifdef CONFIG_DEBUG_FS
66
67static int
68qcaspi_info_show(struct seq_file *s, void *what)
69{
70 struct qcaspi *qca = s->private;
71
72 seq_printf(s, "RX buffer size : %lu\n",
73 (unsigned long)qca->buffer_size);
74
75 seq_puts(s, "TX ring state : ");
76
77 if (qca->txr.skb[qca->txr.head] == NULL)
78 seq_puts(s, "empty");
79 else if (qca->txr.skb[qca->txr.tail])
80 seq_puts(s, "full");
81 else
82 seq_puts(s, "in use");
83
84 seq_puts(s, "\n");
85
86 seq_printf(s, "TX ring size : %u\n",
87 qca->txr.size);
88
89 seq_printf(s, "Sync state : %u (",
90 (unsigned int)qca->sync);
91 switch (qca->sync) {
92 case QCASPI_SYNC_UNKNOWN:
93 seq_puts(s, "QCASPI_SYNC_UNKNOWN");
94 break;
95 case QCASPI_SYNC_RESET:
96 seq_puts(s, "QCASPI_SYNC_RESET");
97 break;
98 case QCASPI_SYNC_READY:
99 seq_puts(s, "QCASPI_SYNC_READY");
100 break;
101 default:
102 seq_puts(s, "INVALID");
103 break;
104 }
105 seq_puts(s, ")\n");
106
107 seq_printf(s, "IRQ : %d\n",
108 qca->spi_dev->irq);
109 seq_printf(s, "INTR REQ : %u\n",
110 qca->intr_req);
111 seq_printf(s, "INTR SVC : %u\n",
112 qca->intr_svc);
113
114 seq_printf(s, "SPI max speed : %lu\n",
115 (unsigned long)qca->spi_dev->max_speed_hz);
116 seq_printf(s, "SPI mode : %x\n",
117 qca->spi_dev->mode);
118 seq_printf(s, "SPI chip select : %u\n",
119 (unsigned int)qca->spi_dev->chip_select);
120 seq_printf(s, "SPI legacy mode : %u\n",
121 (unsigned int)qca->legacy_mode);
122 seq_printf(s, "SPI burst length : %u\n",
123 (unsigned int)qca->burst_len);
124
125 return 0;
126}
127
128static int
129qcaspi_info_open(struct inode *inode, struct file *file)
130{
131 return single_open(file, qcaspi_info_show, inode->i_private);
132}
133
134static const struct file_operations qcaspi_info_ops = {
135 .open = qcaspi_info_open,
136 .read = seq_read,
137 .llseek = seq_lseek,
138 .release = single_release,
139};
140
141void
142qcaspi_init_device_debugfs(struct qcaspi *qca)
143{
144 struct dentry *device_root;
145
146 device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev), NULL);
147 qca->device_root = device_root;
148
149 if (IS_ERR(device_root) || !device_root) {
150 pr_warn("failed to create debugfs directory for %s\n",
151 dev_name(&qca->net_dev->dev));
152 return;
153 }
154 debugfs_create_file("info", S_IFREG | S_IRUGO, device_root, qca,
155 &qcaspi_info_ops);
156}
157
158void
159qcaspi_remove_device_debugfs(struct qcaspi *qca)
160{
161 debugfs_remove_recursive(qca->device_root);
162}
163
164#else /* CONFIG_DEBUG_FS */
165
166void
167qcaspi_init_device_debugfs(struct qcaspi *qca)
168{
169}
170
171void
172qcaspi_remove_device_debugfs(struct qcaspi *qca)
173{
174}
175
176#endif
177
178static void
179qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
180{
181 struct qcaspi *qca = netdev_priv(dev);
182
183 strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
184 strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
185 strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
186 strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev),
187 sizeof(p->bus_info));
188}
189
190static int
191qcaspi_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
192{
193 cmd->transceiver = XCVR_INTERNAL;
194 cmd->supported = SUPPORTED_10baseT_Half;
195 ethtool_cmd_speed_set(cmd, SPEED_10);
196 cmd->duplex = DUPLEX_HALF;
197 cmd->port = PORT_OTHER;
198 cmd->autoneg = AUTONEG_DISABLE;
199
200 return 0;
201}
202
203static void
204qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
205{
206 struct qcaspi *qca = netdev_priv(dev);
207 struct qcaspi_stats *st = &qca->stats;
208
209 memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
210}
211
212static void
213qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
214{
215 switch (stringset) {
216 case ETH_SS_STATS:
217 memcpy(buf, &qcaspi_gstrings_stats,
218 sizeof(qcaspi_gstrings_stats));
219 break;
220 default:
221 WARN_ON(1);
222 break;
223 }
224}
225
226static int
227qcaspi_get_sset_count(struct net_device *dev, int sset)
228{
229 switch (sset) {
230 case ETH_SS_STATS:
231 return ARRAY_SIZE(qcaspi_gstrings_stats);
232 default:
233 return -EINVAL;
234 }
235}
236
237static int
238qcaspi_get_regs_len(struct net_device *dev)
239{
240 return sizeof(u32) * QCASPI_MAX_REGS;
241}
242
243static void
244qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
245{
246 struct qcaspi *qca = netdev_priv(dev);
247 u32 *regs_buff = p;
248 unsigned int i;
249
250 regs->version = 1;
251 memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
252
253 for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
254 u16 offset, value;
255
256 qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
257 offset = qcaspi_spi_regs[i] >> 8;
258 regs_buff[offset] = value;
259 }
260}
261
262static void
263qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
264{
265 struct qcaspi *qca = netdev_priv(dev);
266
267 ring->rx_max_pending = 4;
268 ring->tx_max_pending = TX_RING_MAX_LEN;
269 ring->rx_pending = 4;
270 ring->tx_pending = qca->txr.count;
271}
272
273static int
274qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
275{
276 struct qcaspi *qca = netdev_priv(dev);
277
278 if ((ring->rx_pending) ||
279 (ring->rx_mini_pending) ||
280 (ring->rx_jumbo_pending))
281 return -EINVAL;
282
283 if (netif_running(dev))
284 qcaspi_netdev_close(dev);
285
286 qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
287 qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
288
289 if (netif_running(dev))
290 qcaspi_netdev_open(dev);
291
292 return 0;
293}
294
295static const struct ethtool_ops qcaspi_ethtool_ops = {
296 .get_drvinfo = qcaspi_get_drvinfo,
297 .get_link = ethtool_op_get_link,
298 .get_settings = qcaspi_get_settings,
299 .get_ethtool_stats = qcaspi_get_ethtool_stats,
300 .get_strings = qcaspi_get_strings,
301 .get_sset_count = qcaspi_get_sset_count,
302 .get_regs_len = qcaspi_get_regs_len,
303 .get_regs = qcaspi_get_regs,
304 .get_ringparam = qcaspi_get_ringparam,
305 .set_ringparam = qcaspi_set_ringparam,
306};
307
308void qcaspi_set_ethtool_ops(struct net_device *dev)
309{
310 dev->ethtool_ops = &qcaspi_ethtool_ops;
311}
diff --git a/drivers/net/ethernet/qualcomm/qca_debug.h b/drivers/net/ethernet/qualcomm/qca_debug.h
new file mode 100644
index 000000000000..46a785844421
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_debug.h
@@ -0,0 +1,34 @@
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#ifndef _QCA_DEBUG_H
24#define _QCA_DEBUG_H
25
26#include "qca_spi.h"
27
28void qcaspi_init_device_debugfs(struct qcaspi *qca);
29
30void qcaspi_remove_device_debugfs(struct qcaspi *qca);
31
32void qcaspi_set_ethtool_ops(struct net_device *dev);
33
34#endif /* _QCA_DEBUG_H */
diff --git a/drivers/net/ethernet/qualcomm/qca_framing.c b/drivers/net/ethernet/qualcomm/qca_framing.c
new file mode 100644
index 000000000000..faa924c85e29
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_framing.c
@@ -0,0 +1,156 @@
1/*
2 * Copyright (c) 2011, 2012, 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/* Atheros ethernet framing. Every Ethernet frame is surrounded
21 * by an atheros frame while transmitted over a serial channel;
22 */
23
24#include <linux/kernel.h>
25
26#include "qca_framing.h"
27
28u16
29qcafrm_create_header(u8 *buf, u16 length)
30{
31 __le16 len;
32
33 if (!buf)
34 return 0;
35
36 len = cpu_to_le16(length);
37
38 buf[0] = 0xAA;
39 buf[1] = 0xAA;
40 buf[2] = 0xAA;
41 buf[3] = 0xAA;
42 buf[4] = len & 0xff;
43 buf[5] = (len >> 8) & 0xff;
44 buf[6] = 0;
45 buf[7] = 0;
46
47 return QCAFRM_HEADER_LEN;
48}
49
50u16
51qcafrm_create_footer(u8 *buf)
52{
53 if (!buf)
54 return 0;
55
56 buf[0] = 0x55;
57 buf[1] = 0x55;
58 return QCAFRM_FOOTER_LEN;
59}
60
61/* Gather received bytes and try to extract a full ethernet frame by
62 * following a simple state machine.
63 *
64 * Return: QCAFRM_GATHER No ethernet frame fully received yet.
65 * QCAFRM_NOHEAD Header expected but not found.
66 * QCAFRM_INVLEN Atheros frame length is invalid
67 * QCAFRM_NOTAIL Footer expected but not found.
68 * > 0 Number of byte in the fully received
69 * Ethernet frame
70 */
71
72s32
73qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_byte)
74{
75 s32 ret = QCAFRM_GATHER;
76 u16 len;
77
78 switch (handle->state) {
79 case QCAFRM_HW_LEN0:
80 case QCAFRM_HW_LEN1:
81 /* by default, just go to next state */
82 handle->state--;
83
84 if (recv_byte != 0x00) {
85 /* first two bytes of length must be 0 */
86 handle->state = QCAFRM_HW_LEN0;
87 }
88 break;
89 case QCAFRM_HW_LEN2:
90 case QCAFRM_HW_LEN3:
91 handle->state--;
92 break;
93 /* 4 bytes header pattern */
94 case QCAFRM_WAIT_AA1:
95 case QCAFRM_WAIT_AA2:
96 case QCAFRM_WAIT_AA3:
97 case QCAFRM_WAIT_AA4:
98 if (recv_byte != 0xAA) {
99 ret = QCAFRM_NOHEAD;
100 handle->state = QCAFRM_HW_LEN0;
101 } else {
102 handle->state--;
103 }
104 break;
105 /* 2 bytes length. */
106 /* Borrow offset field to hold length for now. */
107 case QCAFRM_WAIT_LEN_BYTE0:
108 handle->offset = recv_byte;
109 handle->state = QCAFRM_WAIT_LEN_BYTE1;
110 break;
111 case QCAFRM_WAIT_LEN_BYTE1:
112 handle->offset = handle->offset | (recv_byte << 8);
113 handle->state = QCAFRM_WAIT_RSVD_BYTE1;
114 break;
115 case QCAFRM_WAIT_RSVD_BYTE1:
116 handle->state = QCAFRM_WAIT_RSVD_BYTE2;
117 break;
118 case QCAFRM_WAIT_RSVD_BYTE2:
119 len = handle->offset;
120 if (len > buf_len || len < QCAFRM_ETHMINLEN) {
121 ret = QCAFRM_INVLEN;
122 handle->state = QCAFRM_HW_LEN0;
123 } else {
124 handle->state = (enum qcafrm_state)(len + 1);
125 /* Remaining number of bytes. */
126 handle->offset = 0;
127 }
128 break;
129 default:
130 /* Receiving Ethernet frame itself. */
131 buf[handle->offset] = recv_byte;
132 handle->offset++;
133 handle->state--;
134 break;
135 case QCAFRM_WAIT_551:
136 if (recv_byte != 0x55) {
137 ret = QCAFRM_NOTAIL;
138 handle->state = QCAFRM_HW_LEN0;
139 } else {
140 handle->state = QCAFRM_WAIT_552;
141 }
142 break;
143 case QCAFRM_WAIT_552:
144 if (recv_byte != 0x55) {
145 ret = QCAFRM_NOTAIL;
146 handle->state = QCAFRM_HW_LEN0;
147 } else {
148 ret = handle->offset;
149 /* Frame is fully received. */
150 handle->state = QCAFRM_HW_LEN0;
151 }
152 break;
153 }
154
155 return ret;
156}
diff --git a/drivers/net/ethernet/qualcomm/qca_framing.h b/drivers/net/ethernet/qualcomm/qca_framing.h
new file mode 100644
index 000000000000..5d965959c978
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_framing.h
@@ -0,0 +1,134 @@
1/*
2 * Copyright (c) 2011, 2012, 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/* Atheros Ethernet framing. Every Ethernet frame is surrounded by an atheros
21 * frame while transmitted over a serial channel.
22 */
23
24#ifndef _QCA_FRAMING_H
25#define _QCA_FRAMING_H
26
27#include <linux/if_ether.h>
28#include <linux/if_vlan.h>
29#include <linux/types.h>
30
31/* Frame is currently being received */
32#define QCAFRM_GATHER 0
33
34/* No header byte while expecting it */
35#define QCAFRM_NOHEAD (QCAFRM_ERR_BASE - 1)
36
37/* No tailer byte while expecting it */
38#define QCAFRM_NOTAIL (QCAFRM_ERR_BASE - 2)
39
40/* Frame length is invalid */
41#define QCAFRM_INVLEN (QCAFRM_ERR_BASE - 3)
42
43/* Frame length is invalid */
44#define QCAFRM_INVFRAME (QCAFRM_ERR_BASE - 4)
45
46/* Min/Max Ethernet MTU */
47#define QCAFRM_ETHMINMTU 46
48#define QCAFRM_ETHMAXMTU 1500
49
50/* Min/Max frame lengths */
51#define QCAFRM_ETHMINLEN (QCAFRM_ETHMINMTU + ETH_HLEN)
52#define QCAFRM_ETHMAXLEN (QCAFRM_ETHMAXMTU + VLAN_ETH_HLEN)
53
54/* QCA7K header len */
55#define QCAFRM_HEADER_LEN 8
56
57/* QCA7K footer len */
58#define QCAFRM_FOOTER_LEN 2
59
60/* QCA7K Framing. */
61#define QCAFRM_ERR_BASE -1000
62
63enum qcafrm_state {
64 QCAFRM_HW_LEN0 = 0x8000,
65 QCAFRM_HW_LEN1 = QCAFRM_HW_LEN0 - 1,
66 QCAFRM_HW_LEN2 = QCAFRM_HW_LEN1 - 1,
67 QCAFRM_HW_LEN3 = QCAFRM_HW_LEN2 - 1,
68
69 /* Waiting first 0xAA of header */
70 QCAFRM_WAIT_AA1 = QCAFRM_HW_LEN3 - 1,
71
72 /* Waiting second 0xAA of header */
73 QCAFRM_WAIT_AA2 = QCAFRM_WAIT_AA1 - 1,
74
75 /* Waiting third 0xAA of header */
76 QCAFRM_WAIT_AA3 = QCAFRM_WAIT_AA2 - 1,
77
78 /* Waiting fourth 0xAA of header */
79 QCAFRM_WAIT_AA4 = QCAFRM_WAIT_AA3 - 1,
80
81 /* Waiting Byte 0-1 of length (litte endian) */
82 QCAFRM_WAIT_LEN_BYTE0 = QCAFRM_WAIT_AA4 - 1,
83 QCAFRM_WAIT_LEN_BYTE1 = QCAFRM_WAIT_AA4 - 2,
84
85 /* Reserved bytes */
86 QCAFRM_WAIT_RSVD_BYTE1 = QCAFRM_WAIT_AA4 - 3,
87 QCAFRM_WAIT_RSVD_BYTE2 = QCAFRM_WAIT_AA4 - 4,
88
89 /* The frame length is used as the state until
90 * the end of the Ethernet frame
91 * Waiting for first 0x55 of footer
92 */
93 QCAFRM_WAIT_551 = 1,
94
95 /* Waiting for second 0x55 of footer */
96 QCAFRM_WAIT_552 = QCAFRM_WAIT_551 - 1
97};
98
99/* Structure to maintain the frame decoding during reception. */
100
101struct qcafrm_handle {
102 /* Current decoding state */
103 enum qcafrm_state state;
104
105 /* Offset in buffer (borrowed for length too) */
106 s16 offset;
107
108 /* Frame length as kept by this module */
109 u16 len;
110};
111
112u16 qcafrm_create_header(u8 *buf, u16 len);
113
114u16 qcafrm_create_footer(u8 *buf);
115
116static inline void qcafrm_fsm_init(struct qcafrm_handle *handle)
117{
118 handle->state = QCAFRM_HW_LEN0;
119}
120
121/* Gather received bytes and try to extract a full Ethernet frame
122 * by following a simple state machine.
123 *
124 * Return: QCAFRM_GATHER No Ethernet frame fully received yet.
125 * QCAFRM_NOHEAD Header expected but not found.
126 * QCAFRM_INVLEN QCA7K frame length is invalid
127 * QCAFRM_NOTAIL Footer expected but not found.
128 * > 0 Number of byte in the fully received
129 * Ethernet frame
130 */
131
132s32 qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_byte);
133
134#endif /* _QCA_FRAMING_H */
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c
new file mode 100644
index 000000000000..74eb520e2649
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_spi.c
@@ -0,0 +1,993 @@
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 module implements the Qualcomm Atheros SPI protocol for
21 * kernel-based SPI device; it is essentially an Ethernet-to-SPI
22 * serial converter;
23 */
24
25#include <linux/errno.h>
26#include <linux/etherdevice.h>
27#include <linux/if_arp.h>
28#include <linux/if_ether.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/jiffies.h>
32#include <linux/kernel.h>
33#include <linux/kthread.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/netdevice.h>
37#include <linux/of.h>
38#include <linux/of_device.h>
39#include <linux/of_net.h>
40#include <linux/sched.h>
41#include <linux/skbuff.h>
42#include <linux/spi/spi.h>
43#include <linux/types.h>
44#include <linux/version.h>
45
46#include "qca_7k.h"
47#include "qca_debug.h"
48#include "qca_framing.h"
49#include "qca_spi.h"
50
51#define MAX_DMA_BURST_LEN 5000
52
53/* Modules parameters */
54#define QCASPI_CLK_SPEED_MIN 1000000
55#define QCASPI_CLK_SPEED_MAX 16000000
56#define QCASPI_CLK_SPEED 8000000
57static int qcaspi_clkspeed;
58module_param(qcaspi_clkspeed, int, 0);
59MODULE_PARM_DESC(qcaspi_clkspeed, "SPI bus clock speed (Hz). Use 1000000-16000000.");
60
61#define QCASPI_BURST_LEN_MIN 1
62#define QCASPI_BURST_LEN_MAX MAX_DMA_BURST_LEN
63static int qcaspi_burst_len = MAX_DMA_BURST_LEN;
64module_param(qcaspi_burst_len, int, 0);
65MODULE_PARM_DESC(qcaspi_burst_len, "Number of data bytes per burst. Use 1-5000.");
66
67#define QCASPI_PLUGGABLE_MIN 0
68#define QCASPI_PLUGGABLE_MAX 1
69static int qcaspi_pluggable = QCASPI_PLUGGABLE_MIN;
70module_param(qcaspi_pluggable, int, 0);
71MODULE_PARM_DESC(qcaspi_pluggable, "Pluggable SPI connection (yes/no).");
72
73#define QCASPI_MTU QCAFRM_ETHMAXMTU
74#define QCASPI_TX_TIMEOUT (1 * HZ)
75#define QCASPI_QCA7K_REBOOT_TIME_MS 1000
76
77static void
78start_spi_intr_handling(struct qcaspi *qca, u16 *intr_cause)
79{
80 *intr_cause = 0;
81
82 qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, 0);
83 qcaspi_read_register(qca, SPI_REG_INTR_CAUSE, intr_cause);
84 netdev_dbg(qca->net_dev, "interrupts: 0x%04x\n", *intr_cause);
85}
86
87static void
88end_spi_intr_handling(struct qcaspi *qca, u16 intr_cause)
89{
90 u16 intr_enable = (SPI_INT_CPU_ON |
91 SPI_INT_PKT_AVLBL |
92 SPI_INT_RDBUF_ERR |
93 SPI_INT_WRBUF_ERR);
94
95 qcaspi_write_register(qca, SPI_REG_INTR_CAUSE, intr_cause);
96 qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, intr_enable);
97 netdev_dbg(qca->net_dev, "acking int: 0x%04x\n", intr_cause);
98}
99
100static u32
101qcaspi_write_burst(struct qcaspi *qca, u8 *src, u32 len)
102{
103 __be16 cmd;
104 struct spi_message *msg = &qca->spi_msg2;
105 struct spi_transfer *transfer = &qca->spi_xfer2[0];
106 int ret;
107
108 cmd = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL);
109 transfer->tx_buf = &cmd;
110 transfer->rx_buf = NULL;
111 transfer->len = QCASPI_CMD_LEN;
112 transfer = &qca->spi_xfer2[1];
113 transfer->tx_buf = src;
114 transfer->rx_buf = NULL;
115 transfer->len = len;
116
117 ret = spi_sync(qca->spi_dev, msg);
118
119 if (ret || (msg->actual_length != QCASPI_CMD_LEN + len)) {
120 qcaspi_spi_error(qca);
121 return 0;
122 }
123
124 return len;
125}
126
127static u32
128qcaspi_write_legacy(struct qcaspi *qca, u8 *src, u32 len)
129{
130 struct spi_message *msg = &qca->spi_msg1;
131 struct spi_transfer *transfer = &qca->spi_xfer1;
132 int ret;
133
134 transfer->tx_buf = src;
135 transfer->rx_buf = NULL;
136 transfer->len = len;
137
138 ret = spi_sync(qca->spi_dev, msg);
139
140 if (ret || (msg->actual_length != len)) {
141 qcaspi_spi_error(qca);
142 return 0;
143 }
144
145 return len;
146}
147
148static u32
149qcaspi_read_burst(struct qcaspi *qca, u8 *dst, u32 len)
150{
151 struct spi_message *msg = &qca->spi_msg2;
152 __be16 cmd;
153 struct spi_transfer *transfer = &qca->spi_xfer2[0];
154 int ret;
155
156 cmd = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL);
157 transfer->tx_buf = &cmd;
158 transfer->rx_buf = NULL;
159 transfer->len = QCASPI_CMD_LEN;
160 transfer = &qca->spi_xfer2[1];
161 transfer->tx_buf = NULL;
162 transfer->rx_buf = dst;
163 transfer->len = len;
164
165 ret = spi_sync(qca->spi_dev, msg);
166
167 if (ret || (msg->actual_length != QCASPI_CMD_LEN + len)) {
168 qcaspi_spi_error(qca);
169 return 0;
170 }
171
172 return len;
173}
174
175static u32
176qcaspi_read_legacy(struct qcaspi *qca, u8 *dst, u32 len)
177{
178 struct spi_message *msg = &qca->spi_msg1;
179 struct spi_transfer *transfer = &qca->spi_xfer1;
180 int ret;
181
182 transfer->tx_buf = NULL;
183 transfer->rx_buf = dst;
184 transfer->len = len;
185
186 ret = spi_sync(qca->spi_dev, msg);
187
188 if (ret || (msg->actual_length != len)) {
189 qcaspi_spi_error(qca);
190 return 0;
191 }
192
193 return len;
194}
195
196static int
197qcaspi_tx_frame(struct qcaspi *qca, struct sk_buff *skb)
198{
199 u32 count;
200 u32 written;
201 u32 offset;
202 u32 len;
203
204 len = skb->len;
205
206 qcaspi_write_register(qca, SPI_REG_BFR_SIZE, len);
207 if (qca->legacy_mode)
208 qcaspi_tx_cmd(qca, QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL);
209
210 offset = 0;
211 while (len) {
212 count = len;
213 if (count > qca->burst_len)
214 count = qca->burst_len;
215
216 if (qca->legacy_mode) {
217 written = qcaspi_write_legacy(qca,
218 skb->data + offset,
219 count);
220 } else {
221 written = qcaspi_write_burst(qca,
222 skb->data + offset,
223 count);
224 }
225
226 if (written != count)
227 return -1;
228
229 offset += count;
230 len -= count;
231 }
232
233 return 0;
234}
235
236static int
237qcaspi_transmit(struct qcaspi *qca)
238{
239 struct net_device_stats *n_stats = &qca->net_dev->stats;
240 u16 available = 0;
241 u32 pkt_len;
242 u16 new_head;
243 u16 packets = 0;
244
245 if (qca->txr.skb[qca->txr.head] == NULL)
246 return 0;
247
248 qcaspi_read_register(qca, SPI_REG_WRBUF_SPC_AVA, &available);
249
250 while (qca->txr.skb[qca->txr.head]) {
251 pkt_len = qca->txr.skb[qca->txr.head]->len + QCASPI_HW_PKT_LEN;
252
253 if (available < pkt_len) {
254 if (packets == 0)
255 qca->stats.write_buf_miss++;
256 break;
257 }
258
259 if (qcaspi_tx_frame(qca, qca->txr.skb[qca->txr.head]) == -1) {
260 qca->stats.write_err++;
261 return -1;
262 }
263
264 packets++;
265 n_stats->tx_packets++;
266 n_stats->tx_bytes += qca->txr.skb[qca->txr.head]->len;
267 available -= pkt_len;
268
269 /* remove the skb from the queue */
270 /* XXX After inconsistent lock states netif_tx_lock()
271 * has been replaced by netif_tx_lock_bh() and so on.
272 */
273 netif_tx_lock_bh(qca->net_dev);
274 dev_kfree_skb(qca->txr.skb[qca->txr.head]);
275 qca->txr.skb[qca->txr.head] = NULL;
276 qca->txr.size -= pkt_len;
277 new_head = qca->txr.head + 1;
278 if (new_head >= qca->txr.count)
279 new_head = 0;
280 qca->txr.head = new_head;
281 if (netif_queue_stopped(qca->net_dev))
282 netif_wake_queue(qca->net_dev);
283 netif_tx_unlock_bh(qca->net_dev);
284 }
285
286 return 0;
287}
288
289static int
290qcaspi_receive(struct qcaspi *qca)
291{
292 struct net_device *net_dev = qca->net_dev;
293 struct net_device_stats *n_stats = &net_dev->stats;
294 u16 available = 0;
295 u32 bytes_read;
296 u8 *cp;
297
298 /* Allocate rx SKB if we don't have one available. */
299 if (!qca->rx_skb) {
300 qca->rx_skb = netdev_alloc_skb(net_dev,
301 net_dev->mtu + VLAN_ETH_HLEN);
302 if (!qca->rx_skb) {
303 netdev_dbg(net_dev, "out of RX resources\n");
304 qca->stats.out_of_mem++;
305 return -1;
306 }
307 }
308
309 /* Read the packet size. */
310 qcaspi_read_register(qca, SPI_REG_RDBUF_BYTE_AVA, &available);
311 netdev_dbg(net_dev, "qcaspi_receive: SPI_REG_RDBUF_BYTE_AVA: Value: %08x\n",
312 available);
313
314 if (available == 0) {
315 netdev_dbg(net_dev, "qcaspi_receive called without any data being available!\n");
316 return -1;
317 }
318
319 qcaspi_write_register(qca, SPI_REG_BFR_SIZE, available);
320
321 if (qca->legacy_mode)
322 qcaspi_tx_cmd(qca, QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL);
323
324 while (available) {
325 u32 count = available;
326
327 if (count > qca->burst_len)
328 count = qca->burst_len;
329
330 if (qca->legacy_mode) {
331 bytes_read = qcaspi_read_legacy(qca, qca->rx_buffer,
332 count);
333 } else {
334 bytes_read = qcaspi_read_burst(qca, qca->rx_buffer,
335 count);
336 }
337
338 netdev_dbg(net_dev, "available: %d, byte read: %d\n",
339 available, bytes_read);
340
341 if (bytes_read) {
342 available -= bytes_read;
343 } else {
344 qca->stats.read_err++;
345 return -1;
346 }
347
348 cp = qca->rx_buffer;
349
350 while ((bytes_read--) && (qca->rx_skb)) {
351 s32 retcode;
352
353 retcode = qcafrm_fsm_decode(&qca->frm_handle,
354 qca->rx_skb->data,
355 skb_tailroom(qca->rx_skb),
356 *cp);
357 cp++;
358 switch (retcode) {
359 case QCAFRM_GATHER:
360 case QCAFRM_NOHEAD:
361 break;
362 case QCAFRM_NOTAIL:
363 netdev_dbg(net_dev, "no RX tail\n");
364 n_stats->rx_errors++;
365 n_stats->rx_dropped++;
366 break;
367 case QCAFRM_INVLEN:
368 netdev_dbg(net_dev, "invalid RX length\n");
369 n_stats->rx_errors++;
370 n_stats->rx_dropped++;
371 break;
372 default:
373 qca->rx_skb->dev = qca->net_dev;
374 n_stats->rx_packets++;
375 n_stats->rx_bytes += retcode;
376 skb_put(qca->rx_skb, retcode);
377 qca->rx_skb->protocol = eth_type_trans(
378 qca->rx_skb, qca->rx_skb->dev);
379 qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
380 netif_rx_ni(qca->rx_skb);
381 qca->rx_skb = netdev_alloc_skb(net_dev,
382 net_dev->mtu + VLAN_ETH_HLEN);
383 if (!qca->rx_skb) {
384 netdev_dbg(net_dev, "out of RX resources\n");
385 n_stats->rx_errors++;
386 qca->stats.out_of_mem++;
387 break;
388 }
389 }
390 }
391 }
392
393 return 0;
394}
395
396/* Check that tx ring stores only so much bytes
397 * that fit into the internal QCA buffer.
398 */
399
400static int
401qcaspi_tx_ring_has_space(struct tx_ring *txr)
402{
403 if (txr->skb[txr->tail])
404 return 0;
405
406 return (txr->size + QCAFRM_ETHMAXLEN < QCASPI_HW_BUF_LEN) ? 1 : 0;
407}
408
409/* Flush the tx ring. This function is only safe to
410 * call from the qcaspi_spi_thread.
411 */
412
413static void
414qcaspi_flush_tx_ring(struct qcaspi *qca)
415{
416 int i;
417
418 /* XXX After inconsistent lock states netif_tx_lock()
419 * has been replaced by netif_tx_lock_bh() and so on.
420 */
421 netif_tx_lock_bh(qca->net_dev);
422 for (i = 0; i < TX_RING_MAX_LEN; i++) {
423 if (qca->txr.skb[i]) {
424 dev_kfree_skb(qca->txr.skb[i]);
425 qca->txr.skb[i] = NULL;
426 qca->net_dev->stats.tx_dropped++;
427 }
428 }
429 qca->txr.tail = 0;
430 qca->txr.head = 0;
431 qca->txr.size = 0;
432 netif_tx_unlock_bh(qca->net_dev);
433}
434
435static void
436qcaspi_qca7k_sync(struct qcaspi *qca, int event)
437{
438 u16 signature = 0;
439 u16 spi_config;
440 u16 wrbuf_space = 0;
441 static u16 reset_count;
442
443 if (event == QCASPI_EVENT_CPUON) {
444 /* Read signature twice, if not valid
445 * go back to unknown state.
446 */
447 qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature);
448 qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature);
449 if (signature != QCASPI_GOOD_SIGNATURE) {
450 qca->sync = QCASPI_SYNC_UNKNOWN;
451 netdev_dbg(qca->net_dev, "sync: got CPU on, but signature was invalid, restart\n");
452 } else {
453 /* ensure that the WRBUF is empty */
454 qcaspi_read_register(qca, SPI_REG_WRBUF_SPC_AVA,
455 &wrbuf_space);
456 if (wrbuf_space != QCASPI_HW_BUF_LEN) {
457 netdev_dbg(qca->net_dev, "sync: got CPU on, but wrbuf not empty. reset!\n");
458 qca->sync = QCASPI_SYNC_UNKNOWN;
459 } else {
460 netdev_dbg(qca->net_dev, "sync: got CPU on, now in sync\n");
461 qca->sync = QCASPI_SYNC_READY;
462 return;
463 }
464 }
465 }
466
467 switch (qca->sync) {
468 case QCASPI_SYNC_READY:
469 /* Read signature, if not valid go to unknown state. */
470 qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature);
471 if (signature != QCASPI_GOOD_SIGNATURE) {
472 qca->sync = QCASPI_SYNC_UNKNOWN;
473 netdev_dbg(qca->net_dev, "sync: bad signature, restart\n");
474 /* don't reset right away */
475 return;
476 }
477 break;
478 case QCASPI_SYNC_UNKNOWN:
479 /* Read signature, if not valid stay in unknown state */
480 qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature);
481 if (signature != QCASPI_GOOD_SIGNATURE) {
482 netdev_dbg(qca->net_dev, "sync: could not read signature to reset device, retry.\n");
483 return;
484 }
485
486 /* TODO: use GPIO to reset QCA7000 in legacy mode*/
487 netdev_dbg(qca->net_dev, "sync: resetting device.\n");
488 qcaspi_read_register(qca, SPI_REG_SPI_CONFIG, &spi_config);
489 spi_config |= QCASPI_SLAVE_RESET_BIT;
490 qcaspi_write_register(qca, SPI_REG_SPI_CONFIG, spi_config);
491
492 qca->sync = QCASPI_SYNC_RESET;
493 qca->stats.trig_reset++;
494 reset_count = 0;
495 break;
496 case QCASPI_SYNC_RESET:
497 reset_count++;
498 netdev_dbg(qca->net_dev, "sync: waiting for CPU on, count %u.\n",
499 reset_count);
500 if (reset_count >= QCASPI_RESET_TIMEOUT) {
501 /* reset did not seem to take place, try again */
502 qca->sync = QCASPI_SYNC_UNKNOWN;
503 qca->stats.reset_timeout++;
504 netdev_dbg(qca->net_dev, "sync: reset timeout, restarting process.\n");
505 }
506 break;
507 }
508}
509
510static int
511qcaspi_spi_thread(void *data)
512{
513 struct qcaspi *qca = data;
514 u16 intr_cause = 0;
515
516 netdev_info(qca->net_dev, "SPI thread created\n");
517 while (!kthread_should_stop()) {
518 set_current_state(TASK_INTERRUPTIBLE);
519 if ((qca->intr_req == qca->intr_svc) &&
520 (qca->txr.skb[qca->txr.head] == NULL) &&
521 (qca->sync == QCASPI_SYNC_READY))
522 schedule();
523
524 set_current_state(TASK_RUNNING);
525
526 netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n",
527 qca->intr_req - qca->intr_svc,
528 qca->txr.skb[qca->txr.head]);
529
530 qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE);
531
532 if (qca->sync != QCASPI_SYNC_READY) {
533 netdev_dbg(qca->net_dev, "sync: not ready %u, turn off carrier and flush\n",
534 (unsigned int)qca->sync);
535 netif_stop_queue(qca->net_dev);
536 netif_carrier_off(qca->net_dev);
537 qcaspi_flush_tx_ring(qca);
538 msleep(QCASPI_QCA7K_REBOOT_TIME_MS);
539 }
540
541 if (qca->intr_svc != qca->intr_req) {
542 qca->intr_svc = qca->intr_req;
543 start_spi_intr_handling(qca, &intr_cause);
544
545 if (intr_cause & SPI_INT_CPU_ON) {
546 qcaspi_qca7k_sync(qca, QCASPI_EVENT_CPUON);
547
548 /* not synced. */
549 if (qca->sync != QCASPI_SYNC_READY)
550 continue;
551
552 qca->stats.device_reset++;
553 netif_wake_queue(qca->net_dev);
554 netif_carrier_on(qca->net_dev);
555 }
556
557 if (intr_cause & SPI_INT_RDBUF_ERR) {
558 /* restart sync */
559 netdev_dbg(qca->net_dev, "===> rdbuf error!\n");
560 qca->stats.read_buf_err++;
561 qca->sync = QCASPI_SYNC_UNKNOWN;
562 continue;
563 }
564
565 if (intr_cause & SPI_INT_WRBUF_ERR) {
566 /* restart sync */
567 netdev_dbg(qca->net_dev, "===> wrbuf error!\n");
568 qca->stats.write_buf_err++;
569 qca->sync = QCASPI_SYNC_UNKNOWN;
570 continue;
571 }
572
573 /* can only handle other interrupts
574 * if sync has occured
575 */
576 if (qca->sync == QCASPI_SYNC_READY) {
577 if (intr_cause & SPI_INT_PKT_AVLBL)
578 qcaspi_receive(qca);
579 }
580
581 end_spi_intr_handling(qca, intr_cause);
582 }
583
584 if (qca->sync == QCASPI_SYNC_READY)
585 qcaspi_transmit(qca);
586 }
587 set_current_state(TASK_RUNNING);
588 netdev_info(qca->net_dev, "SPI thread exit\n");
589
590 return 0;
591}
592
593static irqreturn_t
594qcaspi_intr_handler(int irq, void *data)
595{
596 struct qcaspi *qca = data;
597
598 qca->intr_req++;
599 if (qca->spi_thread &&
600 qca->spi_thread->state != TASK_RUNNING)
601 wake_up_process(qca->spi_thread);
602
603 return IRQ_HANDLED;
604}
605
606int
607qcaspi_netdev_open(struct net_device *dev)
608{
609 struct qcaspi *qca = netdev_priv(dev);
610 int ret = 0;
611
612 if (!qca)
613 return -EINVAL;
614
615 qca->intr_req = 1;
616 qca->intr_svc = 0;
617 qca->sync = QCASPI_SYNC_UNKNOWN;
618 qcafrm_fsm_init(&qca->frm_handle);
619
620 qca->spi_thread = kthread_run((void *)qcaspi_spi_thread,
621 qca, "%s", dev->name);
622
623 if (IS_ERR(qca->spi_thread)) {
624 netdev_err(dev, "%s: unable to start kernel thread.\n",
625 QCASPI_DRV_NAME);
626 return PTR_ERR(qca->spi_thread);
627 }
628
629 ret = request_irq(qca->spi_dev->irq, qcaspi_intr_handler, 0,
630 dev->name, qca);
631 if (ret) {
632 netdev_err(dev, "%s: unable to get IRQ %d (irqval=%d).\n",
633 QCASPI_DRV_NAME, qca->spi_dev->irq, ret);
634 kthread_stop(qca->spi_thread);
635 return ret;
636 }
637
638 netif_start_queue(qca->net_dev);
639
640 return 0;
641}
642
643int
644qcaspi_netdev_close(struct net_device *dev)
645{
646 struct qcaspi *qca = netdev_priv(dev);
647
648 netif_stop_queue(dev);
649
650 qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, 0);
651 free_irq(qca->spi_dev->irq, qca);
652
653 kthread_stop(qca->spi_thread);
654 qca->spi_thread = NULL;
655 qcaspi_flush_tx_ring(qca);
656
657 return 0;
658}
659
660static netdev_tx_t
661qcaspi_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
662{
663 u32 frame_len;
664 u8 *ptmp;
665 struct qcaspi *qca = netdev_priv(dev);
666 u16 new_tail;
667 struct sk_buff *tskb;
668 u8 pad_len = 0;
669
670 if (skb->len < QCAFRM_ETHMINLEN)
671 pad_len = QCAFRM_ETHMINLEN - skb->len;
672
673 if (qca->txr.skb[qca->txr.tail]) {
674 netdev_warn(qca->net_dev, "queue was unexpectedly full!\n");
675 netif_stop_queue(qca->net_dev);
676 qca->stats.ring_full++;
677 return NETDEV_TX_BUSY;
678 }
679
680 if ((skb_headroom(skb) < QCAFRM_HEADER_LEN) ||
681 (skb_tailroom(skb) < QCAFRM_FOOTER_LEN + pad_len)) {
682 tskb = skb_copy_expand(skb, QCAFRM_HEADER_LEN,
683 QCAFRM_FOOTER_LEN + pad_len, GFP_ATOMIC);
684 if (!tskb) {
685 netdev_dbg(qca->net_dev, "could not allocate tx_buff\n");
686 qca->stats.out_of_mem++;
687 return NETDEV_TX_BUSY;
688 }
689 dev_kfree_skb(skb);
690 skb = tskb;
691 }
692
693 frame_len = skb->len + pad_len;
694
695 ptmp = skb_push(skb, QCAFRM_HEADER_LEN);
696 qcafrm_create_header(ptmp, frame_len);
697
698 if (pad_len) {
699 ptmp = skb_put(skb, pad_len);
700 memset(ptmp, 0, pad_len);
701 }
702
703 ptmp = skb_put(skb, QCAFRM_FOOTER_LEN);
704 qcafrm_create_footer(ptmp);
705
706 netdev_dbg(qca->net_dev, "Tx-ing packet: Size: 0x%08x\n",
707 skb->len);
708
709 qca->txr.size += skb->len + QCASPI_HW_PKT_LEN;
710
711 new_tail = qca->txr.tail + 1;
712 if (new_tail >= qca->txr.count)
713 new_tail = 0;
714
715 qca->txr.skb[qca->txr.tail] = skb;
716 qca->txr.tail = new_tail;
717
718 if (!qcaspi_tx_ring_has_space(&qca->txr)) {
719 netif_stop_queue(qca->net_dev);
720 qca->stats.ring_full++;
721 }
722
723 dev->trans_start = jiffies;
724
725 if (qca->spi_thread &&
726 qca->spi_thread->state != TASK_RUNNING)
727 wake_up_process(qca->spi_thread);
728
729 return NETDEV_TX_OK;
730}
731
732static void
733qcaspi_netdev_tx_timeout(struct net_device *dev)
734{
735 struct qcaspi *qca = netdev_priv(dev);
736
737 netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
738 jiffies, jiffies - dev->trans_start);
739 qca->net_dev->stats.tx_errors++;
740 /* wake the queue if there is room */
741 if (qcaspi_tx_ring_has_space(&qca->txr))
742 netif_wake_queue(dev);
743}
744
745static int
746qcaspi_netdev_init(struct net_device *dev)
747{
748 struct qcaspi *qca = netdev_priv(dev);
749
750 dev->mtu = QCASPI_MTU;
751 dev->type = ARPHRD_ETHER;
752 qca->clkspeed = qcaspi_clkspeed;
753 qca->burst_len = qcaspi_burst_len;
754 qca->spi_thread = NULL;
755 qca->buffer_size = (dev->mtu + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN +
756 QCAFRM_FOOTER_LEN + 4) * 4;
757
758 memset(&qca->stats, 0, sizeof(struct qcaspi_stats));
759
760 qca->rx_buffer = kmalloc(qca->buffer_size, GFP_KERNEL);
761 if (!qca->rx_buffer)
762 return -ENOBUFS;
763
764 qca->rx_skb = netdev_alloc_skb(dev, qca->net_dev->mtu + VLAN_ETH_HLEN);
765 if (!qca->rx_skb) {
766 kfree(qca->rx_buffer);
767 netdev_info(qca->net_dev, "Failed to allocate RX sk_buff.\n");
768 return -ENOBUFS;
769 }
770
771 return 0;
772}
773
774static void
775qcaspi_netdev_uninit(struct net_device *dev)
776{
777 struct qcaspi *qca = netdev_priv(dev);
778
779 kfree(qca->rx_buffer);
780 qca->buffer_size = 0;
781 if (qca->rx_skb)
782 dev_kfree_skb(qca->rx_skb);
783}
784
785static int
786qcaspi_netdev_change_mtu(struct net_device *dev, int new_mtu)
787{
788 if ((new_mtu < QCAFRM_ETHMINMTU) || (new_mtu > QCAFRM_ETHMAXMTU))
789 return -EINVAL;
790
791 dev->mtu = new_mtu;
792
793 return 0;
794}
795
796static const struct net_device_ops qcaspi_netdev_ops = {
797 .ndo_init = qcaspi_netdev_init,
798 .ndo_uninit = qcaspi_netdev_uninit,
799 .ndo_open = qcaspi_netdev_open,
800 .ndo_stop = qcaspi_netdev_close,
801 .ndo_start_xmit = qcaspi_netdev_xmit,
802 .ndo_change_mtu = qcaspi_netdev_change_mtu,
803 .ndo_set_mac_address = eth_mac_addr,
804 .ndo_tx_timeout = qcaspi_netdev_tx_timeout,
805 .ndo_validate_addr = eth_validate_addr,
806};
807
808static void
809qcaspi_netdev_setup(struct net_device *dev)
810{
811 struct qcaspi *qca = NULL;
812
813 ether_setup(dev);
814
815 dev->netdev_ops = &qcaspi_netdev_ops;
816 qcaspi_set_ethtool_ops(dev);
817 dev->watchdog_timeo = QCASPI_TX_TIMEOUT;
818 dev->flags = IFF_MULTICAST;
819 dev->tx_queue_len = 100;
820
821 qca = netdev_priv(dev);
822 memset(qca, 0, sizeof(struct qcaspi));
823
824 memset(&qca->spi_xfer1, 0, sizeof(struct spi_transfer));
825 memset(&qca->spi_xfer2, 0, sizeof(struct spi_transfer) * 2);
826
827 spi_message_init(&qca->spi_msg1);
828 spi_message_add_tail(&qca->spi_xfer1, &qca->spi_msg1);
829
830 spi_message_init(&qca->spi_msg2);
831 spi_message_add_tail(&qca->spi_xfer2[0], &qca->spi_msg2);
832 spi_message_add_tail(&qca->spi_xfer2[1], &qca->spi_msg2);
833
834 memset(&qca->txr, 0, sizeof(qca->txr));
835 qca->txr.count = TX_RING_MAX_LEN;
836}
837
838static const struct of_device_id qca_spi_of_match[] = {
839 { .compatible = "qca,qca7000" },
840 { /* sentinel */ }
841};
842MODULE_DEVICE_TABLE(of, qca_spi_of_match);
843
844static int
845qca_spi_probe(struct spi_device *spi_device)
846{
847 struct qcaspi *qca = NULL;
848 struct net_device *qcaspi_devs = NULL;
849 u8 legacy_mode = 0;
850 u16 signature;
851 const char *mac;
852
853 if (!spi_device->dev.of_node) {
854 dev_err(&spi_device->dev, "Missing device tree\n");
855 return -EINVAL;
856 }
857
858 legacy_mode = of_property_read_bool(spi_device->dev.of_node,
859 "qca,legacy-mode");
860
861 if (qcaspi_clkspeed == 0) {
862 if (spi_device->max_speed_hz)
863 qcaspi_clkspeed = spi_device->max_speed_hz;
864 else
865 qcaspi_clkspeed = QCASPI_CLK_SPEED;
866 }
867
868 if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) ||
869 (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) {
870 dev_info(&spi_device->dev, "Invalid clkspeed: %d\n",
871 qcaspi_clkspeed);
872 return -EINVAL;
873 }
874
875 if ((qcaspi_burst_len < QCASPI_BURST_LEN_MIN) ||
876 (qcaspi_burst_len > QCASPI_BURST_LEN_MAX)) {
877 dev_info(&spi_device->dev, "Invalid burst len: %d\n",
878 qcaspi_burst_len);
879 return -EINVAL;
880 }
881
882 if ((qcaspi_pluggable < QCASPI_PLUGGABLE_MIN) ||
883 (qcaspi_pluggable > QCASPI_PLUGGABLE_MAX)) {
884 dev_info(&spi_device->dev, "Invalid pluggable: %d\n",
885 qcaspi_pluggable);
886 return -EINVAL;
887 }
888
889 dev_info(&spi_device->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n",
890 QCASPI_DRV_VERSION,
891 qcaspi_clkspeed,
892 qcaspi_burst_len,
893 qcaspi_pluggable);
894
895 spi_device->mode = SPI_MODE_3;
896 spi_device->max_speed_hz = qcaspi_clkspeed;
897 if (spi_setup(spi_device) < 0) {
898 dev_err(&spi_device->dev, "Unable to setup SPI device\n");
899 return -EFAULT;
900 }
901
902 qcaspi_devs = alloc_etherdev(sizeof(struct qcaspi));
903 if (!qcaspi_devs)
904 return -ENOMEM;
905
906 qcaspi_netdev_setup(qcaspi_devs);
907
908 qca = netdev_priv(qcaspi_devs);
909 if (!qca) {
910 free_netdev(qcaspi_devs);
911 dev_err(&spi_device->dev, "Fail to retrieve private structure\n");
912 return -ENOMEM;
913 }
914 qca->net_dev = qcaspi_devs;
915 qca->spi_dev = spi_device;
916 qca->legacy_mode = legacy_mode;
917
918 mac = of_get_mac_address(spi_device->dev.of_node);
919
920 if (mac)
921 ether_addr_copy(qca->net_dev->dev_addr, mac);
922
923 if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
924 eth_hw_addr_random(qca->net_dev);
925 dev_info(&spi_device->dev, "Using random MAC address: %pM\n",
926 qca->net_dev->dev_addr);
927 }
928
929 netif_carrier_off(qca->net_dev);
930
931 if (!qcaspi_pluggable) {
932 qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature);
933 qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature);
934
935 if (signature != QCASPI_GOOD_SIGNATURE) {
936 dev_err(&spi_device->dev, "Invalid signature (0x%04X)\n",
937 signature);
938 free_netdev(qcaspi_devs);
939 return -EFAULT;
940 }
941 }
942
943 if (register_netdev(qcaspi_devs)) {
944 dev_info(&spi_device->dev, "Unable to register net device %s\n",
945 qcaspi_devs->name);
946 free_netdev(qcaspi_devs);
947 return -EFAULT;
948 }
949
950 spi_set_drvdata(spi_device, qcaspi_devs);
951
952 qcaspi_init_device_debugfs(qca);
953
954 return 0;
955}
956
957static int
958qca_spi_remove(struct spi_device *spi_device)
959{
960 struct net_device *qcaspi_devs = spi_get_drvdata(spi_device);
961 struct qcaspi *qca = netdev_priv(qcaspi_devs);
962
963 qcaspi_remove_device_debugfs(qca);
964
965 unregister_netdev(qcaspi_devs);
966 free_netdev(qcaspi_devs);
967
968 return 0;
969}
970
971static const struct spi_device_id qca_spi_id[] = {
972 { "qca7000", 0 },
973 { /* sentinel */ }
974};
975MODULE_DEVICE_TABLE(spi, qca_spi_id);
976
977static struct spi_driver qca_spi_driver = {
978 .driver = {
979 .name = QCASPI_DRV_NAME,
980 .owner = THIS_MODULE,
981 .of_match_table = qca_spi_of_match,
982 },
983 .id_table = qca_spi_id,
984 .probe = qca_spi_probe,
985 .remove = qca_spi_remove,
986};
987module_spi_driver(qca_spi_driver);
988
989MODULE_DESCRIPTION("Qualcomm Atheros SPI Driver");
990MODULE_AUTHOR("Qualcomm Atheros Communications");
991MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
992MODULE_LICENSE("Dual BSD/GPL");
993MODULE_VERSION(QCASPI_DRV_VERSION);
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.h b/drivers/net/ethernet/qualcomm/qca_spi.h
new file mode 100644
index 000000000000..6e31a0e744a4
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_spi.h
@@ -0,0 +1,114 @@
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/* Qualcomm Atheros SPI register definition.
21 *
22 * This module is designed to define the Qualcomm Atheros SPI register
23 * placeholders;
24 */
25
26#ifndef _QCA_SPI_H
27#define _QCA_SPI_H
28
29#include <linux/netdevice.h>
30#include <linux/sched.h>
31#include <linux/skbuff.h>
32#include <linux/spi/spi.h>
33#include <linux/types.h>
34
35#include "qca_framing.h"
36
37#define QCASPI_DRV_VERSION "0.2.7-i"
38#define QCASPI_DRV_NAME "qcaspi"
39
40#define QCASPI_GOOD_SIGNATURE 0xAA55
41
42#define TX_RING_MAX_LEN 10
43#define TX_RING_MIN_LEN 2
44
45/* sync related constants */
46#define QCASPI_SYNC_UNKNOWN 0
47#define QCASPI_SYNC_RESET 1
48#define QCASPI_SYNC_READY 2
49
50#define QCASPI_RESET_TIMEOUT 10
51
52/* sync events */
53#define QCASPI_EVENT_UPDATE 0
54#define QCASPI_EVENT_CPUON 1
55
56struct tx_ring {
57 struct sk_buff *skb[TX_RING_MAX_LEN];
58 u16 head;
59 u16 tail;
60 u16 size;
61 u16 count;
62};
63
64struct qcaspi_stats {
65 u64 trig_reset;
66 u64 device_reset;
67 u64 reset_timeout;
68 u64 read_err;
69 u64 write_err;
70 u64 read_buf_err;
71 u64 write_buf_err;
72 u64 out_of_mem;
73 u64 write_buf_miss;
74 u64 ring_full;
75 u64 spi_err;
76};
77
78struct qcaspi {
79 struct net_device *net_dev;
80 struct spi_device *spi_dev;
81 struct task_struct *spi_thread;
82
83 struct tx_ring txr;
84 struct qcaspi_stats stats;
85
86 struct spi_message spi_msg1;
87 struct spi_message spi_msg2;
88 struct spi_transfer spi_xfer1;
89 struct spi_transfer spi_xfer2[2];
90
91 u8 *rx_buffer;
92 u32 buffer_size;
93 u8 sync;
94
95 struct qcafrm_handle frm_handle;
96 struct sk_buff *rx_skb;
97
98 unsigned int intr_req;
99 unsigned int intr_svc;
100
101#ifdef CONFIG_DEBUG_FS
102 struct dentry *device_root;
103#endif
104
105 /* user configurable options */
106 u32 clkspeed;
107 u8 legacy_mode;
108 u16 burst_len;
109};
110
111int qcaspi_netdev_open(struct net_device *dev);
112int qcaspi_netdev_close(struct net_device *dev);
113
114#endif /* _QCA_SPI_H */