blob: 89cba6741e7f7682ab34a64f5a9718c25881a053 [file] [log] [blame]
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +00001/*
2 * Ethernet driver for the WIZnet W5100 chip.
3 *
4 * Copyright (C) 2006-2008 WIZnet Co.,Ltd.
5 * Copyright (C) 2012 Mike Sinkovsky <msink@permonline.ru>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/kconfig.h>
13#include <linux/netdevice.h>
14#include <linux/etherdevice.h>
15#include <linux/platform_device.h>
16#include <linux/platform_data/wiznet.h>
17#include <linux/ethtool.h>
18#include <linux/skbuff.h>
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/delay.h>
22#include <linux/slab.h>
23#include <linux/spinlock.h>
24#include <linux/io.h>
25#include <linux/ioport.h>
26#include <linux/interrupt.h>
Geert Uytterhoeven64d176f2012-04-12 09:19:23 +000027#include <linux/irq.h>
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000028#include <linux/gpio.h>
29
Akinobu Mita850576c2016-04-15 00:11:30 +090030#include "w5100.h"
31
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000032#define DRV_NAME "w5100"
33#define DRV_VERSION "2012-04-04"
34
35MODULE_DESCRIPTION("WIZnet W5100 Ethernet driver v"DRV_VERSION);
36MODULE_AUTHOR("Mike Sinkovsky <msink@permonline.ru>");
37MODULE_ALIAS("platform:"DRV_NAME);
38MODULE_LICENSE("GPL");
39
40/*
41 * Registers
42 */
43#define W5100_COMMON_REGS 0x0000
44#define W5100_MR 0x0000 /* Mode Register */
45#define MR_RST 0x80 /* S/W reset */
46#define MR_PB 0x10 /* Ping block */
47#define MR_AI 0x02 /* Address Auto-Increment */
48#define MR_IND 0x01 /* Indirect mode */
49#define W5100_SHAR 0x0009 /* Source MAC address */
50#define W5100_IR 0x0015 /* Interrupt Register */
51#define W5100_IMR 0x0016 /* Interrupt Mask Register */
52#define IR_S0 0x01 /* S0 interrupt */
53#define W5100_RTR 0x0017 /* Retry Time-value Register */
54#define RTR_DEFAULT 2000 /* =0x07d0 (2000) */
55#define W5100_RMSR 0x001a /* Receive Memory Size */
56#define W5100_TMSR 0x001b /* Transmit Memory Size */
57#define W5100_COMMON_REGS_LEN 0x0040
58
59#define W5100_S0_REGS 0x0400
60#define W5100_S0_MR 0x0400 /* S0 Mode Register */
Joe Perchesdbedd442015-03-06 20:49:12 -080061#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscuous) */
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000062#define S0_MR_MACRAW_MF 0x44 /* MAC RAW mode (filtered) */
63#define W5100_S0_CR 0x0401 /* S0 Command Register */
64#define S0_CR_OPEN 0x01 /* OPEN command */
65#define S0_CR_CLOSE 0x10 /* CLOSE command */
66#define S0_CR_SEND 0x20 /* SEND command */
67#define S0_CR_RECV 0x40 /* RECV command */
68#define W5100_S0_IR 0x0402 /* S0 Interrupt Register */
69#define S0_IR_SENDOK 0x10 /* complete sending */
70#define S0_IR_RECV 0x04 /* receiving data */
71#define W5100_S0_SR 0x0403 /* S0 Status Register */
72#define S0_SR_MACRAW 0x42 /* mac raw mode */
73#define W5100_S0_TX_FSR 0x0420 /* S0 Transmit free memory size */
74#define W5100_S0_TX_RD 0x0422 /* S0 Transmit memory read pointer */
75#define W5100_S0_TX_WR 0x0424 /* S0 Transmit memory write pointer */
76#define W5100_S0_RX_RSR 0x0426 /* S0 Receive free memory size */
77#define W5100_S0_RX_RD 0x0428 /* S0 Receive memory read pointer */
78#define W5100_S0_REGS_LEN 0x0040
79
80#define W5100_TX_MEM_START 0x4000
Akinobu Mita850576c2016-04-15 00:11:30 +090081#define W5100_TX_MEM_SIZE 0x2000
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000082#define W5100_RX_MEM_START 0x6000
Akinobu Mita850576c2016-04-15 00:11:30 +090083#define W5100_RX_MEM_SIZE 0x2000
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000084
85/*
86 * Device driver private data structure
87 */
Akinobu Mita850576c2016-04-15 00:11:30 +090088
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000089struct w5100_priv {
Akinobu Mita850576c2016-04-15 00:11:30 +090090 const struct w5100_ops *ops;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +000091 int irq;
92 int link_irq;
93 int link_gpio;
94
95 struct napi_struct napi;
96 struct net_device *ndev;
97 bool promisc;
98 u32 msg_enable;
99};
100
101/************************************************************************
102 *
103 * Lowlevel I/O functions
104 *
105 ***********************************************************************/
106
Akinobu Mita850576c2016-04-15 00:11:30 +0900107struct w5100_mmio_priv {
108 void __iomem *base;
109 /* Serialize access in indirect address mode */
110 spinlock_t reg_lock;
111};
112
113static inline struct w5100_mmio_priv *w5100_mmio_priv(struct net_device *dev)
114{
115 return w5100_ops_priv(dev);
116}
117
118static inline void __iomem *w5100_mmio(struct net_device *ndev)
119{
120 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
121
122 return mmio_priv->base;
123}
124
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000125/*
126 * In direct address mode host system can directly access W5100 registers
127 * after mapping to Memory-Mapped I/O space.
128 *
129 * 0x8000 bytes are required for memory space.
130 */
Akinobu Mita850576c2016-04-15 00:11:30 +0900131static inline int w5100_read_direct(struct net_device *ndev, u16 addr)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000132{
Akinobu Mita850576c2016-04-15 00:11:30 +0900133 return ioread8(w5100_mmio(ndev) + (addr << CONFIG_WIZNET_BUS_SHIFT));
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000134}
135
Akinobu Mita850576c2016-04-15 00:11:30 +0900136static inline int __w5100_write_direct(struct net_device *ndev, u16 addr,
137 u8 data)
Akinobu Mitad6586d22016-04-15 00:11:29 +0900138{
Akinobu Mita850576c2016-04-15 00:11:30 +0900139 iowrite8(data, w5100_mmio(ndev) + (addr << CONFIG_WIZNET_BUS_SHIFT));
140
141 return 0;
Akinobu Mitad6586d22016-04-15 00:11:29 +0900142}
143
Akinobu Mita850576c2016-04-15 00:11:30 +0900144static inline int w5100_write_direct(struct net_device *ndev, u16 addr, u8 data)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000145{
Akinobu Mita850576c2016-04-15 00:11:30 +0900146 __w5100_write_direct(ndev, addr, data);
Akinobu Mitad6586d22016-04-15 00:11:29 +0900147 mmiowb();
Akinobu Mita850576c2016-04-15 00:11:30 +0900148
149 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000150}
151
Akinobu Mita850576c2016-04-15 00:11:30 +0900152static int w5100_read16_direct(struct net_device *ndev, u16 addr)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000153{
154 u16 data;
Akinobu Mita850576c2016-04-15 00:11:30 +0900155 data = w5100_read_direct(ndev, addr) << 8;
156 data |= w5100_read_direct(ndev, addr + 1);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000157 return data;
158}
159
Akinobu Mita850576c2016-04-15 00:11:30 +0900160static int w5100_write16_direct(struct net_device *ndev, u16 addr, u16 data)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000161{
Akinobu Mita850576c2016-04-15 00:11:30 +0900162 __w5100_write_direct(ndev, addr, data >> 8);
163 __w5100_write_direct(ndev, addr + 1, data);
Akinobu Mitad6586d22016-04-15 00:11:29 +0900164 mmiowb();
Akinobu Mita850576c2016-04-15 00:11:30 +0900165
166 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000167}
168
Akinobu Mita850576c2016-04-15 00:11:30 +0900169static int w5100_readbulk_direct(struct net_device *ndev, u16 addr, u8 *buf,
170 int len)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000171{
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000172 int i;
173
Akinobu Mita850576c2016-04-15 00:11:30 +0900174 for (i = 0; i < len; i++, addr++)
175 *buf++ = w5100_read_direct(ndev, addr);
176
177 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000178}
179
Akinobu Mita850576c2016-04-15 00:11:30 +0900180static int w5100_writebulk_direct(struct net_device *ndev, u16 addr,
181 const u8 *buf, int len)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000182{
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000183 int i;
184
Akinobu Mita850576c2016-04-15 00:11:30 +0900185 for (i = 0; i < len; i++, addr++)
186 __w5100_write_direct(ndev, addr, *buf++);
187
Akinobu Mitad6586d22016-04-15 00:11:29 +0900188 mmiowb();
Akinobu Mita850576c2016-04-15 00:11:30 +0900189
190 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000191}
192
Akinobu Mita850576c2016-04-15 00:11:30 +0900193static int w5100_mmio_init(struct net_device *ndev)
194{
195 struct platform_device *pdev = to_platform_device(ndev->dev.parent);
196 struct w5100_priv *priv = netdev_priv(ndev);
197 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
198 struct resource *mem;
199
200 spin_lock_init(&mmio_priv->reg_lock);
201
202 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
203 mmio_priv->base = devm_ioremap_resource(&pdev->dev, mem);
204 if (IS_ERR(mmio_priv->base))
205 return PTR_ERR(mmio_priv->base);
206
207 netdev_info(ndev, "at 0x%llx irq %d\n", (u64)mem->start, priv->irq);
208
209 return 0;
210}
211
212static const struct w5100_ops w5100_mmio_direct_ops = {
213 .read = w5100_read_direct,
214 .write = w5100_write_direct,
215 .read16 = w5100_read16_direct,
216 .write16 = w5100_write16_direct,
217 .readbulk = w5100_readbulk_direct,
218 .writebulk = w5100_writebulk_direct,
219 .init = w5100_mmio_init,
220};
221
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000222/*
223 * In indirect address mode host system indirectly accesses registers by
224 * using Indirect Mode Address Register (IDM_AR) and Indirect Mode Data
225 * Register (IDM_DR), which are directly mapped to Memory-Mapped I/O space.
226 * Mode Register (MR) is directly accessible.
227 *
228 * Only 0x04 bytes are required for memory space.
229 */
230#define W5100_IDM_AR 0x01 /* Indirect Mode Address Register */
231#define W5100_IDM_DR 0x03 /* Indirect Mode Data Register */
232
Akinobu Mita850576c2016-04-15 00:11:30 +0900233static int w5100_read_indirect(struct net_device *ndev, u16 addr)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000234{
Akinobu Mita850576c2016-04-15 00:11:30 +0900235 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000236 unsigned long flags;
237 u8 data;
238
Akinobu Mita850576c2016-04-15 00:11:30 +0900239 spin_lock_irqsave(&mmio_priv->reg_lock, flags);
240 w5100_write16_direct(ndev, W5100_IDM_AR, addr);
241 data = w5100_read_direct(ndev, W5100_IDM_DR);
242 spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000243
244 return data;
245}
246
Akinobu Mita850576c2016-04-15 00:11:30 +0900247static int w5100_write_indirect(struct net_device *ndev, u16 addr, u8 data)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000248{
Akinobu Mita850576c2016-04-15 00:11:30 +0900249 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000250 unsigned long flags;
251
Akinobu Mita850576c2016-04-15 00:11:30 +0900252 spin_lock_irqsave(&mmio_priv->reg_lock, flags);
253 w5100_write16_direct(ndev, W5100_IDM_AR, addr);
254 w5100_write_direct(ndev, W5100_IDM_DR, data);
255 spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
256
257 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000258}
259
Akinobu Mita850576c2016-04-15 00:11:30 +0900260static int w5100_read16_indirect(struct net_device *ndev, u16 addr)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000261{
Akinobu Mita850576c2016-04-15 00:11:30 +0900262 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000263 unsigned long flags;
264 u16 data;
265
Akinobu Mita850576c2016-04-15 00:11:30 +0900266 spin_lock_irqsave(&mmio_priv->reg_lock, flags);
267 w5100_write16_direct(ndev, W5100_IDM_AR, addr);
268 data = w5100_read_direct(ndev, W5100_IDM_DR) << 8;
269 data |= w5100_read_direct(ndev, W5100_IDM_DR);
270 spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000271
272 return data;
273}
274
Akinobu Mita850576c2016-04-15 00:11:30 +0900275static int w5100_write16_indirect(struct net_device *ndev, u16 addr, u16 data)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000276{
Akinobu Mita850576c2016-04-15 00:11:30 +0900277 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000278 unsigned long flags;
279
Akinobu Mita850576c2016-04-15 00:11:30 +0900280 spin_lock_irqsave(&mmio_priv->reg_lock, flags);
281 w5100_write16_direct(ndev, W5100_IDM_AR, addr);
282 __w5100_write_direct(ndev, W5100_IDM_DR, data >> 8);
283 w5100_write_direct(ndev, W5100_IDM_DR, data);
284 spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
285
286 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000287}
288
Akinobu Mita850576c2016-04-15 00:11:30 +0900289static int w5100_readbulk_indirect(struct net_device *ndev, u16 addr, u8 *buf,
290 int len)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000291{
Akinobu Mita850576c2016-04-15 00:11:30 +0900292 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000293 unsigned long flags;
294 int i;
295
Akinobu Mita850576c2016-04-15 00:11:30 +0900296 spin_lock_irqsave(&mmio_priv->reg_lock, flags);
297 w5100_write16_direct(ndev, W5100_IDM_AR, addr);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000298
Akinobu Mita850576c2016-04-15 00:11:30 +0900299 for (i = 0; i < len; i++)
300 *buf++ = w5100_read_direct(ndev, W5100_IDM_DR);
301
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000302 mmiowb();
Akinobu Mita850576c2016-04-15 00:11:30 +0900303 spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
304
305 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000306}
307
Akinobu Mita850576c2016-04-15 00:11:30 +0900308static int w5100_writebulk_indirect(struct net_device *ndev, u16 addr,
309 const u8 *buf, int len)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000310{
Akinobu Mita850576c2016-04-15 00:11:30 +0900311 struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000312 unsigned long flags;
313 int i;
314
Akinobu Mita850576c2016-04-15 00:11:30 +0900315 spin_lock_irqsave(&mmio_priv->reg_lock, flags);
316 w5100_write16_direct(ndev, W5100_IDM_AR, addr);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000317
Akinobu Mita850576c2016-04-15 00:11:30 +0900318 for (i = 0; i < len; i++)
319 __w5100_write_direct(ndev, W5100_IDM_DR, *buf++);
320
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000321 mmiowb();
Akinobu Mita850576c2016-04-15 00:11:30 +0900322 spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
323
324 return 0;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000325}
326
Akinobu Mita850576c2016-04-15 00:11:30 +0900327static int w5100_reset_indirect(struct net_device *ndev)
328{
329 w5100_write_direct(ndev, W5100_MR, MR_RST);
330 mdelay(5);
331 w5100_write_direct(ndev, W5100_MR, MR_PB | MR_AI | MR_IND);
332
333 return 0;
334}
335
336static const struct w5100_ops w5100_mmio_indirect_ops = {
337 .read = w5100_read_indirect,
338 .write = w5100_write_indirect,
339 .read16 = w5100_read16_indirect,
340 .write16 = w5100_write16_indirect,
341 .readbulk = w5100_readbulk_indirect,
342 .writebulk = w5100_writebulk_indirect,
343 .init = w5100_mmio_init,
344 .reset = w5100_reset_indirect,
345};
346
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000347#if defined(CONFIG_WIZNET_BUS_DIRECT)
Akinobu Mita850576c2016-04-15 00:11:30 +0900348
349static int w5100_read(struct w5100_priv *priv, u16 addr)
350{
351 return w5100_read_direct(priv->ndev, addr);
352}
353
354static int w5100_write(struct w5100_priv *priv, u16 addr, u8 data)
355{
356 return w5100_write_direct(priv->ndev, addr, data);
357}
358
359static int w5100_read16(struct w5100_priv *priv, u16 addr)
360{
361 return w5100_read16_direct(priv->ndev, addr);
362}
363
364static int w5100_write16(struct w5100_priv *priv, u16 addr, u16 data)
365{
366 return w5100_write16_direct(priv->ndev, addr, data);
367}
368
369static int w5100_readbulk(struct w5100_priv *priv, u16 addr, u8 *buf, int len)
370{
371 return w5100_readbulk_direct(priv->ndev, addr, buf, len);
372}
373
374static int w5100_writebulk(struct w5100_priv *priv, u16 addr, const u8 *buf,
375 int len)
376{
377 return w5100_writebulk_direct(priv->ndev, addr, buf, len);
378}
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000379
380#elif defined(CONFIG_WIZNET_BUS_INDIRECT)
Akinobu Mita850576c2016-04-15 00:11:30 +0900381
382static int w5100_read(struct w5100_priv *priv, u16 addr)
383{
384 return w5100_read_indirect(priv->ndev, addr);
385}
386
387static int w5100_write(struct w5100_priv *priv, u16 addr, u8 data)
388{
389 return w5100_write_indirect(priv->ndev, addr, data);
390}
391
392static int w5100_read16(struct w5100_priv *priv, u16 addr)
393{
394 return w5100_read16_indirect(priv->ndev, addr);
395}
396
397static int w5100_write16(struct w5100_priv *priv, u16 addr, u16 data)
398{
399 return w5100_write16_indirect(priv->ndev, addr, data);
400}
401
402static int w5100_readbulk(struct w5100_priv *priv, u16 addr, u8 *buf, int len)
403{
404 return w5100_readbulk_indirect(priv->ndev, addr, buf, len);
405}
406
407static int w5100_writebulk(struct w5100_priv *priv, u16 addr, const u8 *buf,
408 int len)
409{
410 return w5100_writebulk_indirect(priv->ndev, addr, buf, len);
411}
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000412
413#else /* CONFIG_WIZNET_BUS_ANY */
Akinobu Mita850576c2016-04-15 00:11:30 +0900414
415static int w5100_read(struct w5100_priv *priv, u16 addr)
416{
417 return priv->ops->read(priv->ndev, addr);
418}
419
420static int w5100_write(struct w5100_priv *priv, u16 addr, u8 data)
421{
422 return priv->ops->write(priv->ndev, addr, data);
423}
424
425static int w5100_read16(struct w5100_priv *priv, u16 addr)
426{
427 return priv->ops->read16(priv->ndev, addr);
428}
429
430static int w5100_write16(struct w5100_priv *priv, u16 addr, u16 data)
431{
432 return priv->ops->write16(priv->ndev, addr, data);
433}
434
435static int w5100_readbulk(struct w5100_priv *priv, u16 addr, u8 *buf, int len)
436{
437 return priv->ops->readbulk(priv->ndev, addr, buf, len);
438}
439
440static int w5100_writebulk(struct w5100_priv *priv, u16 addr, const u8 *buf,
441 int len)
442{
443 return priv->ops->writebulk(priv->ndev, addr, buf, len);
444}
445
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000446#endif
447
Akinobu Mita850576c2016-04-15 00:11:30 +0900448static int w5100_readbuf(struct w5100_priv *priv, u16 offset, u8 *buf, int len)
449{
450 u16 addr;
451 int remain = 0;
452 int ret;
453
454 offset %= W5100_RX_MEM_SIZE;
455 addr = W5100_RX_MEM_START + offset;
456
457 if (offset + len > W5100_RX_MEM_SIZE) {
458 remain = (offset + len) % W5100_RX_MEM_SIZE;
459 len = W5100_RX_MEM_SIZE - offset;
460 }
461
462 ret = w5100_readbulk(priv, addr, buf, len);
463 if (ret || !remain)
464 return ret;
465
466 return w5100_readbulk(priv, W5100_RX_MEM_START, buf + len, remain);
467}
468
469static int w5100_writebuf(struct w5100_priv *priv, u16 offset, const u8 *buf,
470 int len)
471{
472 u16 addr;
473 int ret;
474 int remain = 0;
475
476 offset %= W5100_TX_MEM_SIZE;
477 addr = W5100_TX_MEM_START + offset;
478
479 if (offset + len > W5100_TX_MEM_SIZE) {
480 remain = (offset + len) % W5100_TX_MEM_SIZE;
481 len = W5100_TX_MEM_SIZE - offset;
482 }
483
484 ret = w5100_writebulk(priv, addr, buf, len);
485 if (ret || !remain)
486 return ret;
487
488 return w5100_writebulk(priv, W5100_TX_MEM_START, buf + len, remain);
489}
490
491static int w5100_reset(struct w5100_priv *priv)
492{
493 if (priv->ops->reset)
494 return priv->ops->reset(priv->ndev);
495
496 w5100_write(priv, W5100_MR, MR_RST);
497 mdelay(5);
498 w5100_write(priv, W5100_MR, MR_PB);
499
500 return 0;
501}
502
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000503static int w5100_command(struct w5100_priv *priv, u16 cmd)
504{
505 unsigned long timeout = jiffies + msecs_to_jiffies(100);
506
507 w5100_write(priv, W5100_S0_CR, cmd);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000508
509 while (w5100_read(priv, W5100_S0_CR) != 0) {
510 if (time_after(jiffies, timeout))
511 return -EIO;
512 cpu_relax();
513 }
514
515 return 0;
516}
517
518static void w5100_write_macaddr(struct w5100_priv *priv)
519{
520 struct net_device *ndev = priv->ndev;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000521
Akinobu Mita850576c2016-04-15 00:11:30 +0900522 w5100_writebulk(priv, W5100_SHAR, ndev->dev_addr, ETH_ALEN);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000523}
524
525static void w5100_hw_reset(struct w5100_priv *priv)
526{
Akinobu Mita850576c2016-04-15 00:11:30 +0900527 w5100_reset(priv);
528
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000529 w5100_write(priv, W5100_IMR, 0);
530 w5100_write_macaddr(priv);
531
532 /* Configure 16K of internal memory
533 * as 8K RX buffer and 8K TX buffer
534 */
535 w5100_write(priv, W5100_RMSR, 0x03);
536 w5100_write(priv, W5100_TMSR, 0x03);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000537}
538
539static void w5100_hw_start(struct w5100_priv *priv)
540{
541 w5100_write(priv, W5100_S0_MR, priv->promisc ?
542 S0_MR_MACRAW : S0_MR_MACRAW_MF);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000543 w5100_command(priv, S0_CR_OPEN);
544 w5100_write(priv, W5100_IMR, IR_S0);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000545}
546
547static void w5100_hw_close(struct w5100_priv *priv)
548{
549 w5100_write(priv, W5100_IMR, 0);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000550 w5100_command(priv, S0_CR_CLOSE);
551}
552
553/***********************************************************************
554 *
555 * Device driver functions / callbacks
556 *
557 ***********************************************************************/
558
559static void w5100_get_drvinfo(struct net_device *ndev,
560 struct ethtool_drvinfo *info)
561{
562 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
563 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
564 strlcpy(info->bus_info, dev_name(ndev->dev.parent),
565 sizeof(info->bus_info));
566}
567
568static u32 w5100_get_link(struct net_device *ndev)
569{
570 struct w5100_priv *priv = netdev_priv(ndev);
571
572 if (gpio_is_valid(priv->link_gpio))
573 return !!gpio_get_value(priv->link_gpio);
574
575 return 1;
576}
577
578static u32 w5100_get_msglevel(struct net_device *ndev)
579{
580 struct w5100_priv *priv = netdev_priv(ndev);
581
582 return priv->msg_enable;
583}
584
585static void w5100_set_msglevel(struct net_device *ndev, u32 value)
586{
587 struct w5100_priv *priv = netdev_priv(ndev);
588
589 priv->msg_enable = value;
590}
591
592static int w5100_get_regs_len(struct net_device *ndev)
593{
594 return W5100_COMMON_REGS_LEN + W5100_S0_REGS_LEN;
595}
596
597static void w5100_get_regs(struct net_device *ndev,
Akinobu Mita850576c2016-04-15 00:11:30 +0900598 struct ethtool_regs *regs, void *buf)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000599{
600 struct w5100_priv *priv = netdev_priv(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000601
602 regs->version = 1;
Akinobu Mita850576c2016-04-15 00:11:30 +0900603 w5100_readbulk(priv, W5100_COMMON_REGS, buf, W5100_COMMON_REGS_LEN);
604 buf += W5100_COMMON_REGS_LEN;
605 w5100_readbulk(priv, W5100_S0_REGS, buf, W5100_S0_REGS_LEN);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000606}
607
608static void w5100_tx_timeout(struct net_device *ndev)
609{
610 struct w5100_priv *priv = netdev_priv(ndev);
611
612 netif_stop_queue(ndev);
613 w5100_hw_reset(priv);
614 w5100_hw_start(priv);
615 ndev->stats.tx_errors++;
616 ndev->trans_start = jiffies;
617 netif_wake_queue(ndev);
618}
619
620static int w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
621{
622 struct w5100_priv *priv = netdev_priv(ndev);
623 u16 offset;
624
Mike Sinkovsky376b16f2012-04-11 20:14:48 +0000625 netif_stop_queue(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000626
627 offset = w5100_read16(priv, W5100_S0_TX_WR);
628 w5100_writebuf(priv, offset, skb->data, skb->len);
629 w5100_write16(priv, W5100_S0_TX_WR, offset + skb->len);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000630 ndev->stats.tx_bytes += skb->len;
631 ndev->stats.tx_packets++;
632 dev_kfree_skb(skb);
633
634 w5100_command(priv, S0_CR_SEND);
635
636 return NETDEV_TX_OK;
637}
638
639static int w5100_napi_poll(struct napi_struct *napi, int budget)
640{
641 struct w5100_priv *priv = container_of(napi, struct w5100_priv, napi);
642 struct net_device *ndev = priv->ndev;
643 struct sk_buff *skb;
644 int rx_count;
645 u16 rx_len;
646 u16 offset;
647 u8 header[2];
648
649 for (rx_count = 0; rx_count < budget; rx_count++) {
650 u16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR);
651 if (rx_buf_len == 0)
652 break;
653
654 offset = w5100_read16(priv, W5100_S0_RX_RD);
655 w5100_readbuf(priv, offset, header, 2);
656 rx_len = get_unaligned_be16(header) - 2;
657
658 skb = netdev_alloc_skb_ip_align(ndev, rx_len);
659 if (unlikely(!skb)) {
660 w5100_write16(priv, W5100_S0_RX_RD,
661 offset + rx_buf_len);
662 w5100_command(priv, S0_CR_RECV);
663 ndev->stats.rx_dropped++;
664 return -ENOMEM;
665 }
666
667 skb_put(skb, rx_len);
668 w5100_readbuf(priv, offset + 2, skb->data, rx_len);
669 w5100_write16(priv, W5100_S0_RX_RD, offset + 2 + rx_len);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000670 w5100_command(priv, S0_CR_RECV);
671 skb->protocol = eth_type_trans(skb, ndev);
672
673 netif_receive_skb(skb);
674 ndev->stats.rx_packets++;
675 ndev->stats.rx_bytes += rx_len;
676 }
677
678 if (rx_count < budget) {
Yongbae Park5a3dba72015-03-10 11:35:07 +0900679 napi_complete(napi);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000680 w5100_write(priv, W5100_IMR, IR_S0);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000681 }
682
683 return rx_count;
684}
685
686static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)
687{
688 struct net_device *ndev = ndev_instance;
689 struct w5100_priv *priv = netdev_priv(ndev);
690
691 int ir = w5100_read(priv, W5100_S0_IR);
692 if (!ir)
693 return IRQ_NONE;
694 w5100_write(priv, W5100_S0_IR, ir);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000695
Mike Sinkovsky376b16f2012-04-11 20:14:48 +0000696 if (ir & S0_IR_SENDOK) {
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000697 netif_dbg(priv, tx_done, ndev, "tx done\n");
698 netif_wake_queue(ndev);
699 }
700
701 if (ir & S0_IR_RECV) {
702 if (napi_schedule_prep(&priv->napi)) {
703 w5100_write(priv, W5100_IMR, 0);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000704 __napi_schedule(&priv->napi);
705 }
706 }
707
708 return IRQ_HANDLED;
709}
710
711static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)
712{
713 struct net_device *ndev = ndev_instance;
714 struct w5100_priv *priv = netdev_priv(ndev);
715
716 if (netif_running(ndev)) {
717 if (gpio_get_value(priv->link_gpio) != 0) {
718 netif_info(priv, link, ndev, "link is up\n");
719 netif_carrier_on(ndev);
720 } else {
721 netif_info(priv, link, ndev, "link is down\n");
722 netif_carrier_off(ndev);
723 }
724 }
725
726 return IRQ_HANDLED;
727}
728
729static void w5100_set_rx_mode(struct net_device *ndev)
730{
731 struct w5100_priv *priv = netdev_priv(ndev);
732 bool set_promisc = (ndev->flags & IFF_PROMISC) != 0;
733
734 if (priv->promisc != set_promisc) {
735 priv->promisc = set_promisc;
736 w5100_hw_start(priv);
737 }
738}
739
740static int w5100_set_macaddr(struct net_device *ndev, void *addr)
741{
742 struct w5100_priv *priv = netdev_priv(ndev);
743 struct sockaddr *sock_addr = addr;
744
745 if (!is_valid_ether_addr(sock_addr->sa_data))
746 return -EADDRNOTAVAIL;
747 memcpy(ndev->dev_addr, sock_addr->sa_data, ETH_ALEN);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000748 w5100_write_macaddr(priv);
749 return 0;
750}
751
752static int w5100_open(struct net_device *ndev)
753{
754 struct w5100_priv *priv = netdev_priv(ndev);
755
756 netif_info(priv, ifup, ndev, "enabling\n");
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000757 w5100_hw_start(priv);
758 napi_enable(&priv->napi);
759 netif_start_queue(ndev);
760 if (!gpio_is_valid(priv->link_gpio) ||
761 gpio_get_value(priv->link_gpio) != 0)
762 netif_carrier_on(ndev);
763 return 0;
764}
765
766static int w5100_stop(struct net_device *ndev)
767{
768 struct w5100_priv *priv = netdev_priv(ndev);
769
770 netif_info(priv, ifdown, ndev, "shutting down\n");
771 w5100_hw_close(priv);
772 netif_carrier_off(ndev);
773 netif_stop_queue(ndev);
774 napi_disable(&priv->napi);
775 return 0;
776}
777
778static const struct ethtool_ops w5100_ethtool_ops = {
779 .get_drvinfo = w5100_get_drvinfo,
780 .get_msglevel = w5100_get_msglevel,
781 .set_msglevel = w5100_set_msglevel,
782 .get_link = w5100_get_link,
783 .get_regs_len = w5100_get_regs_len,
784 .get_regs = w5100_get_regs,
785};
786
787static const struct net_device_ops w5100_netdev_ops = {
788 .ndo_open = w5100_open,
789 .ndo_stop = w5100_stop,
790 .ndo_start_xmit = w5100_start_tx,
791 .ndo_tx_timeout = w5100_tx_timeout,
792 .ndo_set_rx_mode = w5100_set_rx_mode,
793 .ndo_set_mac_address = w5100_set_macaddr,
794 .ndo_validate_addr = eth_validate_addr,
795 .ndo_change_mtu = eth_change_mtu,
796};
797
Akinobu Mita850576c2016-04-15 00:11:30 +0900798static int w5100_mmio_probe(struct platform_device *pdev)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000799{
Jingoo Han5988aa62013-08-30 14:07:38 +0900800 struct wiznet_platform_data *data = dev_get_platdata(&pdev->dev);
Akinobu Mita850576c2016-04-15 00:11:30 +0900801 u8 *mac_addr = NULL;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000802 struct resource *mem;
Akinobu Mita850576c2016-04-15 00:11:30 +0900803 const struct w5100_ops *ops;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000804 int irq;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000805
Akinobu Mita850576c2016-04-15 00:11:30 +0900806 if (data && is_valid_ether_addr(data->mac_addr))
807 mac_addr = data->mac_addr;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000808
809 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Akinobu Mita850576c2016-04-15 00:11:30 +0900810 if (resource_size(mem) < W5100_BUS_DIRECT_SIZE)
811 ops = &w5100_mmio_indirect_ops;
812 else
813 ops = &w5100_mmio_direct_ops;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000814
815 irq = platform_get_irq(pdev, 0);
816 if (irq < 0)
817 return irq;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000818
Akinobu Mita850576c2016-04-15 00:11:30 +0900819 return w5100_probe(&pdev->dev, ops, sizeof(struct w5100_mmio_priv),
820 mac_addr, irq, data ? data->link_gpio : -EINVAL);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000821}
822
Akinobu Mita850576c2016-04-15 00:11:30 +0900823static int w5100_mmio_remove(struct platform_device *pdev)
824{
825 return w5100_remove(&pdev->dev);
826}
827
828void *w5100_ops_priv(const struct net_device *ndev)
829{
830 return netdev_priv(ndev) +
831 ALIGN(sizeof(struct w5100_priv), NETDEV_ALIGN);
832}
833EXPORT_SYMBOL_GPL(w5100_ops_priv);
834
835int w5100_probe(struct device *dev, const struct w5100_ops *ops,
836 int sizeof_ops_priv, u8 *mac_addr, int irq, int link_gpio)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000837{
838 struct w5100_priv *priv;
839 struct net_device *ndev;
840 int err;
Akinobu Mita850576c2016-04-15 00:11:30 +0900841 size_t alloc_size;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000842
Akinobu Mita850576c2016-04-15 00:11:30 +0900843 alloc_size = sizeof(*priv);
844 if (sizeof_ops_priv) {
845 alloc_size = ALIGN(alloc_size, NETDEV_ALIGN);
846 alloc_size += sizeof_ops_priv;
847 }
848 alloc_size += NETDEV_ALIGN - 1;
849
850 ndev = alloc_etherdev(alloc_size);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000851 if (!ndev)
852 return -ENOMEM;
Akinobu Mita850576c2016-04-15 00:11:30 +0900853 SET_NETDEV_DEV(ndev, dev);
854 dev_set_drvdata(dev, ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000855 priv = netdev_priv(ndev);
856 priv->ndev = ndev;
Akinobu Mita850576c2016-04-15 00:11:30 +0900857 priv->ops = ops;
858 priv->irq = irq;
859 priv->link_gpio = link_gpio;
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000860
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000861 ndev->netdev_ops = &w5100_netdev_ops;
862 ndev->ethtool_ops = &w5100_ethtool_ops;
863 ndev->watchdog_timeo = HZ;
864 netif_napi_add(ndev, &priv->napi, w5100_napi_poll, 16);
865
866 /* This chip doesn't support VLAN packets with normal MTU,
867 * so disable VLAN for this device.
868 */
869 ndev->features |= NETIF_F_VLAN_CHALLENGED;
870
871 err = register_netdev(ndev);
872 if (err < 0)
873 goto err_register;
874
Akinobu Mita850576c2016-04-15 00:11:30 +0900875 if (mac_addr)
876 memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
877 else
878 eth_hw_addr_random(ndev);
879
880 if (priv->ops->init) {
881 err = priv->ops->init(priv->ndev);
882 if (err)
883 goto err_hw;
884 }
885
886 w5100_hw_reset(priv);
887 if (w5100_read16(priv, W5100_RTR) != RTR_DEFAULT) {
888 err = -ENODEV;
889 goto err_hw;
890 }
891
892 err = request_irq(priv->irq, w5100_interrupt, IRQF_TRIGGER_LOW,
893 netdev_name(ndev), ndev);
894 if (err)
895 goto err_hw;
896
897 if (gpio_is_valid(priv->link_gpio)) {
898 char *link_name = devm_kzalloc(dev, 16, GFP_KERNEL);
899
900 if (!link_name) {
901 err = -ENOMEM;
902 goto err_gpio;
903 }
904 snprintf(link_name, 16, "%s-link", netdev_name(ndev));
905 priv->link_irq = gpio_to_irq(priv->link_gpio);
906 if (request_any_context_irq(priv->link_irq, w5100_detect_link,
907 IRQF_TRIGGER_RISING |
908 IRQF_TRIGGER_FALLING,
909 link_name, priv->ndev) < 0)
910 priv->link_gpio = -EINVAL;
911 }
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000912
913 return 0;
914
Akinobu Mita850576c2016-04-15 00:11:30 +0900915err_gpio:
916 free_irq(priv->irq, ndev);
917err_hw:
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000918 unregister_netdev(ndev);
919err_register:
920 free_netdev(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000921 return err;
922}
Akinobu Mita850576c2016-04-15 00:11:30 +0900923EXPORT_SYMBOL_GPL(w5100_probe);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000924
Akinobu Mita850576c2016-04-15 00:11:30 +0900925int w5100_remove(struct device *dev)
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000926{
Akinobu Mita850576c2016-04-15 00:11:30 +0900927 struct net_device *ndev = dev_get_drvdata(dev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000928 struct w5100_priv *priv = netdev_priv(ndev);
929
930 w5100_hw_reset(priv);
931 free_irq(priv->irq, ndev);
932 if (gpio_is_valid(priv->link_gpio))
933 free_irq(priv->link_irq, ndev);
934
935 unregister_netdev(ndev);
936 free_netdev(ndev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000937 return 0;
938}
Akinobu Mita850576c2016-04-15 00:11:30 +0900939EXPORT_SYMBOL_GPL(w5100_remove);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000940
Jingoo Han4294beb2013-03-25 21:02:55 +0000941#ifdef CONFIG_PM_SLEEP
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000942static int w5100_suspend(struct device *dev)
943{
Akinobu Mita850576c2016-04-15 00:11:30 +0900944 struct net_device *ndev = dev_get_drvdata(dev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000945 struct w5100_priv *priv = netdev_priv(ndev);
946
947 if (netif_running(ndev)) {
948 netif_carrier_off(ndev);
949 netif_device_detach(ndev);
950
951 w5100_hw_close(priv);
952 }
953 return 0;
954}
955
956static int w5100_resume(struct device *dev)
957{
Akinobu Mita850576c2016-04-15 00:11:30 +0900958 struct net_device *ndev = dev_get_drvdata(dev);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000959 struct w5100_priv *priv = netdev_priv(ndev);
960
961 if (netif_running(ndev)) {
962 w5100_hw_reset(priv);
963 w5100_hw_start(priv);
964
965 netif_device_attach(ndev);
966 if (!gpio_is_valid(priv->link_gpio) ||
967 gpio_get_value(priv->link_gpio) != 0)
968 netif_carrier_on(ndev);
969 }
970 return 0;
971}
Jingoo Han4294beb2013-03-25 21:02:55 +0000972#endif /* CONFIG_PM_SLEEP */
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000973
Akinobu Mita850576c2016-04-15 00:11:30 +0900974SIMPLE_DEV_PM_OPS(w5100_pm_ops, w5100_suspend, w5100_resume);
975EXPORT_SYMBOL_GPL(w5100_pm_ops);
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000976
Akinobu Mita850576c2016-04-15 00:11:30 +0900977static struct platform_driver w5100_mmio_driver = {
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000978 .driver = {
979 .name = DRV_NAME,
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000980 .pm = &w5100_pm_ops,
981 },
Akinobu Mita850576c2016-04-15 00:11:30 +0900982 .probe = w5100_mmio_probe,
983 .remove = w5100_mmio_remove,
Mike Sinkovsky8b1467a2012-04-04 19:33:54 +0000984};
Akinobu Mita850576c2016-04-15 00:11:30 +0900985module_platform_driver(w5100_mmio_driver);