aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/wiznet/Kconfig2
-rw-r--r--drivers/net/ethernet/wiznet/w5100-spi.c174
-rw-r--r--drivers/net/ethernet/wiznet/w5100.c155
-rw-r--r--drivers/net/ethernet/wiznet/w5100.h6
4 files changed, 289 insertions, 48 deletions
diff --git a/drivers/net/ethernet/wiznet/Kconfig b/drivers/net/ethernet/wiznet/Kconfig
index d1ab353790de..1f15376e9856 100644
--- a/drivers/net/ethernet/wiznet/Kconfig
+++ b/drivers/net/ethernet/wiznet/Kconfig
@@ -70,7 +70,7 @@ config WIZNET_BUS_ANY
70endchoice 70endchoice
71 71
72config WIZNET_W5100_SPI 72config WIZNET_W5100_SPI
73 tristate "WIZnet W5100 Ethernet support for SPI mode" 73 tristate "WIZnet W5100/W5200 Ethernet support for SPI mode"
74 depends on WIZNET_BUS_ANY 74 depends on WIZNET_BUS_ANY
75 depends on SPI 75 depends on SPI
76 ---help--- 76 ---help---
diff --git a/drivers/net/ethernet/wiznet/w5100-spi.c b/drivers/net/ethernet/wiznet/w5100-spi.c
index 32f406cfce4b..598a7b00fdb9 100644
--- a/drivers/net/ethernet/wiznet/w5100-spi.c
+++ b/drivers/net/ethernet/wiznet/w5100-spi.c
@@ -1,9 +1,13 @@
1/* 1/*
2 * Ethernet driver for the WIZnet W5100 chip. 2 * Ethernet driver for the WIZnet W5100/W5200 chip.
3 * 3 *
4 * Copyright (C) 2016 Akinobu Mita <akinobu.mita@gmail.com> 4 * Copyright (C) 2016 Akinobu Mita <akinobu.mita@gmail.com>
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 *
8 * Datasheet:
9 * http://www.wiznet.co.kr/wp-content/uploads/wiznethome/Chip/W5100/Document/W5100_Datasheet_v1.2.6.pdf
10 * http://wiznethome.cafe24.com/wp-content/uploads/wiznethome/Chip/W5200/Documents/W5200_DS_V140E.pdf
7 */ 11 */
8 12
9#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -95,6 +99,7 @@ static int w5100_spi_writebulk(struct net_device *ndev, u16 addr, const u8 *buf,
95 99
96static const struct w5100_ops w5100_spi_ops = { 100static const struct w5100_ops w5100_spi_ops = {
97 .may_sleep = true, 101 .may_sleep = true,
102 .chip_id = W5100,
98 .read = w5100_spi_read, 103 .read = w5100_spi_read,
99 .write = w5100_spi_write, 104 .write = w5100_spi_write,
100 .read16 = w5100_spi_read16, 105 .read16 = w5100_spi_read16,
@@ -103,10 +108,168 @@ static const struct w5100_ops w5100_spi_ops = {
103 .writebulk = w5100_spi_writebulk, 108 .writebulk = w5100_spi_writebulk,
104}; 109};
105 110
111#define W5200_SPI_WRITE_OPCODE 0x80
112
113struct w5200_spi_priv {
114 /* Serialize access to cmd_buf */
115 struct mutex cmd_lock;
116
117 /* DMA (thus cache coherency maintenance) requires the
118 * transfer buffers to live in their own cache lines.
119 */
120 u8 cmd_buf[4] ____cacheline_aligned;
121};
122
123static struct w5200_spi_priv *w5200_spi_priv(struct net_device *ndev)
124{
125 return w5100_ops_priv(ndev);
126}
127
128static int w5200_spi_init(struct net_device *ndev)
129{
130 struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
131
132 mutex_init(&spi_priv->cmd_lock);
133
134 return 0;
135}
136
137static int w5200_spi_read(struct net_device *ndev, u16 addr)
138{
139 struct spi_device *spi = to_spi_device(ndev->dev.parent);
140 u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 1 };
141 u8 data;
142 int ret;
143
144 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
145
146 return ret ? ret : data;
147}
148
149static int w5200_spi_write(struct net_device *ndev, u16 addr, u8 data)
150{
151 struct spi_device *spi = to_spi_device(ndev->dev.parent);
152 u8 cmd[5] = { addr >> 8, addr & 0xff, W5200_SPI_WRITE_OPCODE, 1, data };
153
154 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
155}
156
157static int w5200_spi_read16(struct net_device *ndev, u16 addr)
158{
159 struct spi_device *spi = to_spi_device(ndev->dev.parent);
160 u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 2 };
161 __be16 data;
162 int ret;
163
164 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, sizeof(data));
165
166 return ret ? ret : be16_to_cpu(data);
167}
168
169static int w5200_spi_write16(struct net_device *ndev, u16 addr, u16 data)
170{
171 struct spi_device *spi = to_spi_device(ndev->dev.parent);
172 u8 cmd[6] = {
173 addr >> 8, addr & 0xff,
174 W5200_SPI_WRITE_OPCODE, 2,
175 data >> 8, data & 0xff
176 };
177
178 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
179}
180
181static int w5200_spi_readbulk(struct net_device *ndev, u16 addr, u8 *buf,
182 int len)
183{
184 struct spi_device *spi = to_spi_device(ndev->dev.parent);
185 struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
186 struct spi_transfer xfer[] = {
187 {
188 .tx_buf = spi_priv->cmd_buf,
189 .len = sizeof(spi_priv->cmd_buf),
190 },
191 {
192 .rx_buf = buf,
193 .len = len,
194 },
195 };
196 int ret;
197
198 mutex_lock(&spi_priv->cmd_lock);
199
200 spi_priv->cmd_buf[0] = addr >> 8;
201 spi_priv->cmd_buf[1] = addr;
202 spi_priv->cmd_buf[2] = len >> 8;
203 spi_priv->cmd_buf[3] = len;
204 ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
205
206 mutex_unlock(&spi_priv->cmd_lock);
207
208 return ret;
209}
210
211static int w5200_spi_writebulk(struct net_device *ndev, u16 addr, const u8 *buf,
212 int len)
213{
214 struct spi_device *spi = to_spi_device(ndev->dev.parent);
215 struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
216 struct spi_transfer xfer[] = {
217 {
218 .tx_buf = spi_priv->cmd_buf,
219 .len = sizeof(spi_priv->cmd_buf),
220 },
221 {
222 .tx_buf = buf,
223 .len = len,
224 },
225 };
226 int ret;
227
228 mutex_lock(&spi_priv->cmd_lock);
229
230 spi_priv->cmd_buf[0] = addr >> 8;
231 spi_priv->cmd_buf[1] = addr;
232 spi_priv->cmd_buf[2] = W5200_SPI_WRITE_OPCODE | (len >> 8);
233 spi_priv->cmd_buf[3] = len;
234 ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
235
236 mutex_unlock(&spi_priv->cmd_lock);
237
238 return ret;
239}
240
241static const struct w5100_ops w5200_ops = {
242 .may_sleep = true,
243 .chip_id = W5200,
244 .read = w5200_spi_read,
245 .write = w5200_spi_write,
246 .read16 = w5200_spi_read16,
247 .write16 = w5200_spi_write16,
248 .readbulk = w5200_spi_readbulk,
249 .writebulk = w5200_spi_writebulk,
250 .init = w5200_spi_init,
251};
252
106static int w5100_spi_probe(struct spi_device *spi) 253static int w5100_spi_probe(struct spi_device *spi)
107{ 254{
108 return w5100_probe(&spi->dev, &w5100_spi_ops, 0, NULL, spi->irq, 255 const struct spi_device_id *id = spi_get_device_id(spi);
109 -EINVAL); 256 const struct w5100_ops *ops;
257 int priv_size;
258
259 switch (id->driver_data) {
260 case W5100:
261 ops = &w5100_spi_ops;
262 priv_size = 0;
263 break;
264 case W5200:
265 ops = &w5200_ops;
266 priv_size = sizeof(struct w5200_spi_priv);
267 break;
268 default:
269 return -EINVAL;
270 }
271
272 return w5100_probe(&spi->dev, ops, priv_size, NULL, spi->irq, -EINVAL);
110} 273}
111 274
112static int w5100_spi_remove(struct spi_device *spi) 275static int w5100_spi_remove(struct spi_device *spi)
@@ -115,7 +278,8 @@ static int w5100_spi_remove(struct spi_device *spi)
115} 278}
116 279
117static const struct spi_device_id w5100_spi_ids[] = { 280static const struct spi_device_id w5100_spi_ids[] = {
118 { "w5100", 0 }, 281 { "w5100", W5100 },
282 { "w5200", W5200 },
119 {} 283 {}
120}; 284};
121MODULE_DEVICE_TABLE(spi, w5100_spi_ids); 285MODULE_DEVICE_TABLE(spi, w5100_spi_ids);
@@ -131,6 +295,6 @@ static struct spi_driver w5100_spi_driver = {
131}; 295};
132module_spi_driver(w5100_spi_driver); 296module_spi_driver(w5100_spi_driver);
133 297
134MODULE_DESCRIPTION("WIZnet W5100 Ethernet driver for SPI mode"); 298MODULE_DESCRIPTION("WIZnet W5100/W5200 Ethernet driver for SPI mode");
135MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>"); 299MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
136MODULE_LICENSE("GPL"); 300MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c
index 42a9de4a48b1..09149c9ebeff 100644
--- a/drivers/net/ethernet/wiznet/w5100.c
+++ b/drivers/net/ethernet/wiznet/w5100.c
@@ -38,7 +38,7 @@ MODULE_ALIAS("platform:"DRV_NAME);
38MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
39 39
40/* 40/*
41 * Registers 41 * W5100 and W5100 common registers
42 */ 42 */
43#define W5100_COMMON_REGS 0x0000 43#define W5100_COMMON_REGS 0x0000
44#define W5100_MR 0x0000 /* Mode Register */ 44#define W5100_MR 0x0000 /* Mode Register */
@@ -52,37 +52,69 @@ MODULE_LICENSE("GPL");
52#define IR_S0 0x01 /* S0 interrupt */ 52#define IR_S0 0x01 /* S0 interrupt */
53#define W5100_RTR 0x0017 /* Retry Time-value Register */ 53#define W5100_RTR 0x0017 /* Retry Time-value Register */
54#define RTR_DEFAULT 2000 /* =0x07d0 (2000) */ 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 55#define W5100_COMMON_REGS_LEN 0x0040
58 56
59#define W5100_S0_REGS 0x0400 57#define W5100_Sn_MR 0x0000 /* Sn Mode Register */
60#define W5100_S0_MR 0x0400 /* S0 Mode Register */ 58#define W5100_Sn_CR 0x0001 /* Sn Command Register */
59#define W5100_Sn_IR 0x0002 /* Sn Interrupt Register */
60#define W5100_Sn_SR 0x0003 /* Sn Status Register */
61#define W5100_Sn_TX_FSR 0x0020 /* Sn Transmit free memory size */
62#define W5100_Sn_TX_RD 0x0022 /* Sn Transmit memory read pointer */
63#define W5100_Sn_TX_WR 0x0024 /* Sn Transmit memory write pointer */
64#define W5100_Sn_RX_RSR 0x0026 /* Sn Receive free memory size */
65#define W5100_Sn_RX_RD 0x0028 /* Sn Receive memory read pointer */
66
67#define S0_REGS(priv) (is_w5200(priv) ? W5200_S0_REGS : W5100_S0_REGS)
68
69#define W5100_S0_MR(priv) (S0_REGS(priv) + W5100_Sn_MR)
61#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscuous) */ 70#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscuous) */
62#define S0_MR_MACRAW_MF 0x44 /* MAC RAW mode (filtered) */ 71#define S0_MR_MACRAW_MF 0x44 /* MAC RAW mode (filtered) */
63#define W5100_S0_CR 0x0401 /* S0 Command Register */ 72#define W5100_S0_CR(priv) (S0_REGS(priv) + W5100_Sn_CR)
64#define S0_CR_OPEN 0x01 /* OPEN command */ 73#define S0_CR_OPEN 0x01 /* OPEN command */
65#define S0_CR_CLOSE 0x10 /* CLOSE command */ 74#define S0_CR_CLOSE 0x10 /* CLOSE command */
66#define S0_CR_SEND 0x20 /* SEND command */ 75#define S0_CR_SEND 0x20 /* SEND command */
67#define S0_CR_RECV 0x40 /* RECV command */ 76#define S0_CR_RECV 0x40 /* RECV command */
68#define W5100_S0_IR 0x0402 /* S0 Interrupt Register */ 77#define W5100_S0_IR(priv) (S0_REGS(priv) + W5100_Sn_IR)
69#define S0_IR_SENDOK 0x10 /* complete sending */ 78#define S0_IR_SENDOK 0x10 /* complete sending */
70#define S0_IR_RECV 0x04 /* receiving data */ 79#define S0_IR_RECV 0x04 /* receiving data */
71#define W5100_S0_SR 0x0403 /* S0 Status Register */ 80#define W5100_S0_SR(priv) (S0_REGS(priv) + W5100_Sn_SR)
72#define S0_SR_MACRAW 0x42 /* mac raw mode */ 81#define S0_SR_MACRAW 0x42 /* mac raw mode */
73#define W5100_S0_TX_FSR 0x0420 /* S0 Transmit free memory size */ 82#define W5100_S0_TX_FSR(priv) (S0_REGS(priv) + W5100_Sn_TX_FSR)
74#define W5100_S0_TX_RD 0x0422 /* S0 Transmit memory read pointer */ 83#define W5100_S0_TX_RD(priv) (S0_REGS(priv) + W5100_Sn_TX_RD)
75#define W5100_S0_TX_WR 0x0424 /* S0 Transmit memory write pointer */ 84#define W5100_S0_TX_WR(priv) (S0_REGS(priv) + W5100_Sn_TX_WR)
76#define W5100_S0_RX_RSR 0x0426 /* S0 Receive free memory size */ 85#define W5100_S0_RX_RSR(priv) (S0_REGS(priv) + W5100_Sn_RX_RSR)
77#define W5100_S0_RX_RD 0x0428 /* S0 Receive memory read pointer */ 86#define W5100_S0_RX_RD(priv) (S0_REGS(priv) + W5100_Sn_RX_RD)
87
78#define W5100_S0_REGS_LEN 0x0040 88#define W5100_S0_REGS_LEN 0x0040
79 89
90/*
91 * W5100 specific registers
92 */
93#define W5100_RMSR 0x001a /* Receive Memory Size */
94#define W5100_TMSR 0x001b /* Transmit Memory Size */
95
96#define W5100_S0_REGS 0x0400
97
80#define W5100_TX_MEM_START 0x4000 98#define W5100_TX_MEM_START 0x4000
81#define W5100_TX_MEM_SIZE 0x2000 99#define W5100_TX_MEM_SIZE 0x2000
82#define W5100_RX_MEM_START 0x6000 100#define W5100_RX_MEM_START 0x6000
83#define W5100_RX_MEM_SIZE 0x2000 101#define W5100_RX_MEM_SIZE 0x2000
84 102
85/* 103/*
104 * W5200 specific registers
105 */
106#define W5200_S0_REGS 0x4000
107
108#define W5200_Sn_RXMEM_SIZE(n) (0x401e + (n) * 0x0100) /* Sn RX Memory Size */
109#define W5200_Sn_TXMEM_SIZE(n) (0x401f + (n) * 0x0100) /* Sn TX Memory Size */
110#define W5200_S0_IMR 0x402c /* S0 Interrupt Mask Register */
111
112#define W5200_TX_MEM_START 0x8000
113#define W5200_TX_MEM_SIZE 0x4000
114#define W5200_RX_MEM_START 0xc000
115#define W5200_RX_MEM_SIZE 0x4000
116
117/*
86 * Device driver private data structure 118 * Device driver private data structure
87 */ 119 */
88 120
@@ -105,6 +137,11 @@ struct w5100_priv {
105 struct work_struct restart_work; 137 struct work_struct restart_work;
106}; 138};
107 139
140static inline bool is_w5200(struct w5100_priv *priv)
141{
142 return priv->ops->chip_id == W5200;
143}
144
108/************************************************************************ 145/************************************************************************
109 * 146 *
110 * Lowlevel I/O functions 147 * Lowlevel I/O functions
@@ -217,6 +254,7 @@ static int w5100_mmio_init(struct net_device *ndev)
217} 254}
218 255
219static const struct w5100_ops w5100_mmio_direct_ops = { 256static const struct w5100_ops w5100_mmio_direct_ops = {
257 .chip_id = W5100,
220 .read = w5100_read_direct, 258 .read = w5100_read_direct,
221 .write = w5100_write_direct, 259 .write = w5100_write_direct,
222 .read16 = w5100_read16_direct, 260 .read16 = w5100_read16_direct,
@@ -341,6 +379,7 @@ static int w5100_reset_indirect(struct net_device *ndev)
341} 379}
342 380
343static const struct w5100_ops w5100_mmio_indirect_ops = { 381static const struct w5100_ops w5100_mmio_indirect_ops = {
382 .chip_id = W5100,
344 .read = w5100_read_indirect, 383 .read = w5100_read_indirect,
345 .write = w5100_write_indirect, 384 .write = w5100_write_indirect,
346 .read16 = w5100_read16_indirect, 385 .read16 = w5100_read16_indirect,
@@ -457,20 +496,24 @@ static int w5100_readbuf(struct w5100_priv *priv, u16 offset, u8 *buf, int len)
457 u16 addr; 496 u16 addr;
458 int remain = 0; 497 int remain = 0;
459 int ret; 498 int ret;
499 const u16 mem_start =
500 is_w5200(priv) ? W5200_RX_MEM_START : W5100_RX_MEM_START;
501 const u16 mem_size =
502 is_w5200(priv) ? W5200_RX_MEM_SIZE : W5100_RX_MEM_SIZE;
460 503
461 offset %= W5100_RX_MEM_SIZE; 504 offset %= mem_size;
462 addr = W5100_RX_MEM_START + offset; 505 addr = mem_start + offset;
463 506
464 if (offset + len > W5100_RX_MEM_SIZE) { 507 if (offset + len > mem_size) {
465 remain = (offset + len) % W5100_RX_MEM_SIZE; 508 remain = (offset + len) % mem_size;
466 len = W5100_RX_MEM_SIZE - offset; 509 len = mem_size - offset;
467 } 510 }
468 511
469 ret = w5100_readbulk(priv, addr, buf, len); 512 ret = w5100_readbulk(priv, addr, buf, len);
470 if (ret || !remain) 513 if (ret || !remain)
471 return ret; 514 return ret;
472 515
473 return w5100_readbulk(priv, W5100_RX_MEM_START, buf + len, remain); 516 return w5100_readbulk(priv, mem_start, buf + len, remain);
474} 517}
475 518
476static int w5100_writebuf(struct w5100_priv *priv, u16 offset, const u8 *buf, 519static int w5100_writebuf(struct w5100_priv *priv, u16 offset, const u8 *buf,
@@ -479,20 +522,24 @@ static int w5100_writebuf(struct w5100_priv *priv, u16 offset, const u8 *buf,
479 u16 addr; 522 u16 addr;
480 int ret; 523 int ret;
481 int remain = 0; 524 int remain = 0;
525 const u16 mem_start =
526 is_w5200(priv) ? W5200_TX_MEM_START : W5100_TX_MEM_START;
527 const u16 mem_size =
528 is_w5200(priv) ? W5200_TX_MEM_SIZE : W5100_TX_MEM_SIZE;
482 529
483 offset %= W5100_TX_MEM_SIZE; 530 offset %= mem_size;
484 addr = W5100_TX_MEM_START + offset; 531 addr = mem_start + offset;
485 532
486 if (offset + len > W5100_TX_MEM_SIZE) { 533 if (offset + len > mem_size) {
487 remain = (offset + len) % W5100_TX_MEM_SIZE; 534 remain = (offset + len) % mem_size;
488 len = W5100_TX_MEM_SIZE - offset; 535 len = mem_size - offset;
489 } 536 }
490 537
491 ret = w5100_writebulk(priv, addr, buf, len); 538 ret = w5100_writebulk(priv, addr, buf, len);
492 if (ret || !remain) 539 if (ret || !remain)
493 return ret; 540 return ret;
494 541
495 return w5100_writebulk(priv, W5100_TX_MEM_START, buf + len, remain); 542 return w5100_writebulk(priv, mem_start, buf + len, remain);
496} 543}
497 544
498static int w5100_reset(struct w5100_priv *priv) 545static int w5100_reset(struct w5100_priv *priv)
@@ -511,11 +558,11 @@ static int w5100_command(struct w5100_priv *priv, u16 cmd)
511{ 558{
512 unsigned long timeout; 559 unsigned long timeout;
513 560
514 w5100_write(priv, W5100_S0_CR, cmd); 561 w5100_write(priv, W5100_S0_CR(priv), cmd);
515 562
516 timeout = jiffies + msecs_to_jiffies(100); 563 timeout = jiffies + msecs_to_jiffies(100);
517 564
518 while (w5100_read(priv, W5100_S0_CR) != 0) { 565 while (w5100_read(priv, W5100_S0_CR(priv)) != 0) {
519 if (time_after(jiffies, timeout)) 566 if (time_after(jiffies, timeout))
520 return -EIO; 567 return -EIO;
521 cpu_relax(); 568 cpu_relax();
@@ -531,6 +578,31 @@ static void w5100_write_macaddr(struct w5100_priv *priv)
531 w5100_writebulk(priv, W5100_SHAR, ndev->dev_addr, ETH_ALEN); 578 w5100_writebulk(priv, W5100_SHAR, ndev->dev_addr, ETH_ALEN);
532} 579}
533 580
581static void w5100_memory_configure(struct w5100_priv *priv)
582{
583 /* Configure 16K of internal memory
584 * as 8K RX buffer and 8K TX buffer
585 */
586 w5100_write(priv, W5100_RMSR, 0x03);
587 w5100_write(priv, W5100_TMSR, 0x03);
588}
589
590static void w5200_memory_configure(struct w5100_priv *priv)
591{
592 int i;
593
594 /* Configure internal RX memory as 16K RX buffer and
595 * internal TX memory as 16K TX buffer
596 */
597 w5100_write(priv, W5200_Sn_RXMEM_SIZE(0), 0x10);
598 w5100_write(priv, W5200_Sn_TXMEM_SIZE(0), 0x10);
599
600 for (i = 1; i < 8; i++) {
601 w5100_write(priv, W5200_Sn_RXMEM_SIZE(i), 0);
602 w5100_write(priv, W5200_Sn_TXMEM_SIZE(i), 0);
603 }
604}
605
534static void w5100_hw_reset(struct w5100_priv *priv) 606static void w5100_hw_reset(struct w5100_priv *priv)
535{ 607{
536 w5100_reset(priv); 608 w5100_reset(priv);
@@ -538,16 +610,15 @@ static void w5100_hw_reset(struct w5100_priv *priv)
538 w5100_write(priv, W5100_IMR, 0); 610 w5100_write(priv, W5100_IMR, 0);
539 w5100_write_macaddr(priv); 611 w5100_write_macaddr(priv);
540 612
541 /* Configure 16K of internal memory 613 if (is_w5200(priv))
542 * as 8K RX buffer and 8K TX buffer 614 w5200_memory_configure(priv);
543 */ 615 else
544 w5100_write(priv, W5100_RMSR, 0x03); 616 w5100_memory_configure(priv);
545 w5100_write(priv, W5100_TMSR, 0x03);
546} 617}
547 618
548static void w5100_hw_start(struct w5100_priv *priv) 619static void w5100_hw_start(struct w5100_priv *priv)
549{ 620{
550 w5100_write(priv, W5100_S0_MR, priv->promisc ? 621 w5100_write(priv, W5100_S0_MR(priv), priv->promisc ?
551 S0_MR_MACRAW : S0_MR_MACRAW_MF); 622 S0_MR_MACRAW : S0_MR_MACRAW_MF);
552 w5100_command(priv, S0_CR_OPEN); 623 w5100_command(priv, S0_CR_OPEN);
553 w5100_write(priv, W5100_IMR, IR_S0); 624 w5100_write(priv, W5100_IMR, IR_S0);
@@ -611,7 +682,7 @@ static void w5100_get_regs(struct net_device *ndev,
611 regs->version = 1; 682 regs->version = 1;
612 w5100_readbulk(priv, W5100_COMMON_REGS, buf, W5100_COMMON_REGS_LEN); 683 w5100_readbulk(priv, W5100_COMMON_REGS, buf, W5100_COMMON_REGS_LEN);
613 buf += W5100_COMMON_REGS_LEN; 684 buf += W5100_COMMON_REGS_LEN;
614 w5100_readbulk(priv, W5100_S0_REGS, buf, W5100_S0_REGS_LEN); 685 w5100_readbulk(priv, S0_REGS(priv), buf, W5100_S0_REGS_LEN);
615} 686}
616 687
617static void w5100_restart(struct net_device *ndev) 688static void w5100_restart(struct net_device *ndev)
@@ -649,9 +720,9 @@ static void w5100_tx_skb(struct net_device *ndev, struct sk_buff *skb)
649 struct w5100_priv *priv = netdev_priv(ndev); 720 struct w5100_priv *priv = netdev_priv(ndev);
650 u16 offset; 721 u16 offset;
651 722
652 offset = w5100_read16(priv, W5100_S0_TX_WR); 723 offset = w5100_read16(priv, W5100_S0_TX_WR(priv));
653 w5100_writebuf(priv, offset, skb->data, skb->len); 724 w5100_writebuf(priv, offset, skb->data, skb->len);
654 w5100_write16(priv, W5100_S0_TX_WR, offset + skb->len); 725 w5100_write16(priv, W5100_S0_TX_WR(priv), offset + skb->len);
655 ndev->stats.tx_bytes += skb->len; 726 ndev->stats.tx_bytes += skb->len;
656 ndev->stats.tx_packets++; 727 ndev->stats.tx_packets++;
657 dev_kfree_skb(skb); 728 dev_kfree_skb(skb);
@@ -696,18 +767,18 @@ static struct sk_buff *w5100_rx_skb(struct net_device *ndev)
696 u16 rx_len; 767 u16 rx_len;
697 u16 offset; 768 u16 offset;
698 u8 header[2]; 769 u8 header[2];
699 u16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR); 770 u16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR(priv));
700 771
701 if (rx_buf_len == 0) 772 if (rx_buf_len == 0)
702 return NULL; 773 return NULL;
703 774
704 offset = w5100_read16(priv, W5100_S0_RX_RD); 775 offset = w5100_read16(priv, W5100_S0_RX_RD(priv));
705 w5100_readbuf(priv, offset, header, 2); 776 w5100_readbuf(priv, offset, header, 2);
706 rx_len = get_unaligned_be16(header) - 2; 777 rx_len = get_unaligned_be16(header) - 2;
707 778
708 skb = netdev_alloc_skb_ip_align(ndev, rx_len); 779 skb = netdev_alloc_skb_ip_align(ndev, rx_len);
709 if (unlikely(!skb)) { 780 if (unlikely(!skb)) {
710 w5100_write16(priv, W5100_S0_RX_RD, offset + rx_buf_len); 781 w5100_write16(priv, W5100_S0_RX_RD(priv), offset + rx_buf_len);
711 w5100_command(priv, S0_CR_RECV); 782 w5100_command(priv, S0_CR_RECV);
712 ndev->stats.rx_dropped++; 783 ndev->stats.rx_dropped++;
713 return NULL; 784 return NULL;
@@ -715,7 +786,7 @@ static struct sk_buff *w5100_rx_skb(struct net_device *ndev)
715 786
716 skb_put(skb, rx_len); 787 skb_put(skb, rx_len);
717 w5100_readbuf(priv, offset + 2, skb->data, rx_len); 788 w5100_readbuf(priv, offset + 2, skb->data, rx_len);
718 w5100_write16(priv, W5100_S0_RX_RD, offset + 2 + rx_len); 789 w5100_write16(priv, W5100_S0_RX_RD(priv), offset + 2 + rx_len);
719 w5100_command(priv, S0_CR_RECV); 790 w5100_command(priv, S0_CR_RECV);
720 skb->protocol = eth_type_trans(skb, ndev); 791 skb->protocol = eth_type_trans(skb, ndev);
721 792
@@ -764,10 +835,10 @@ static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)
764 struct net_device *ndev = ndev_instance; 835 struct net_device *ndev = ndev_instance;
765 struct w5100_priv *priv = netdev_priv(ndev); 836 struct w5100_priv *priv = netdev_priv(ndev);
766 837
767 int ir = w5100_read(priv, W5100_S0_IR); 838 int ir = w5100_read(priv, W5100_S0_IR(priv));
768 if (!ir) 839 if (!ir)
769 return IRQ_NONE; 840 return IRQ_NONE;
770 w5100_write(priv, W5100_S0_IR, ir); 841 w5100_write(priv, W5100_S0_IR(priv), ir);
771 842
772 if (ir & S0_IR_SENDOK) { 843 if (ir & S0_IR_SENDOK) {
773 netif_dbg(priv, tx_done, ndev, "tx done\n"); 844 netif_dbg(priv, tx_done, ndev, "tx done\n");
diff --git a/drivers/net/ethernet/wiznet/w5100.h b/drivers/net/ethernet/wiznet/w5100.h
index 69045f0f9e10..9b1fa23b46fe 100644
--- a/drivers/net/ethernet/wiznet/w5100.h
+++ b/drivers/net/ethernet/wiznet/w5100.h
@@ -7,8 +7,14 @@
7 * Licensed under the GPL-2 or later. 7 * Licensed under the GPL-2 or later.
8 */ 8 */
9 9
10enum {
11 W5100,
12 W5200,
13};
14
10struct w5100_ops { 15struct w5100_ops {
11 bool may_sleep; 16 bool may_sleep;
17 int chip_id;
12 int (*read)(struct net_device *ndev, u16 addr); 18 int (*read)(struct net_device *ndev, u16 addr);
13 int (*write)(struct net_device *ndev, u16 addr, u8 data); 19 int (*write)(struct net_device *ndev, u16 addr, u8 data);
14 int (*read16)(struct net_device *ndev, u16 addr); 20 int (*read16)(struct net_device *ndev, u16 addr);